我需要一些帮助,快把我逼疯了。
使用strtok分割我的行。我试着把第一部分分离出来,保存到我的symbolTblChar[lblCnt]中。我似乎不能理解的是,为什么从文件中取出后,我的输出变得如此奇怪
输入 "SPACE n LINE n A1 n A2"
代码char* symbolTblChar[MAX_SYMBOLS][100];
int lblCnt = 0;
char line[LINE_SIZE];
char* chk;
while(fgets(line, sizeof line, fp) != NULL) {
chk = (char*)strtok( line, delims );
printf("Adding %s to symbol table", chk);
*symbolTblChar[lblCnt]=chk + ' ';
lblCnt++;
int t;
for(t = 0; t < lblCnt; t++)
printf("%sn", *symbolTblChar[t]);
}
输出: Adding SPACE to symbol table
Adding LINE to symbol table
LINE
Adding A1 to symbol table
A1
A1
Adding A2 to symbol table
A2
A2
A2
您需要分配和存储字符。在你的代码中,你正在存储字符数组line
的指针,当你读取后续行时,它将被覆盖。
你需要做一些像
*symbolTblChar[lblCnt]= strdup(chk);
也不确定是否需要双char指针作为
char* symbolTblChar[MAX_SYMBOLS][100];
您可以使用下面的操作,它将存储MAX_SYMBOLS
个字符串。
char* symbolTblChar[MAX_SYMBOLS];
我想我明白你想做什么了。除了Rohan的回答,你还在strtok
的使用上磕磕绊绊。虽然这有点像catch 22,因为您正在读取一个用newlines
分隔符号的字符串,但您仍然可以使strtok
工作。但是要明白,当使用strtok
时,对strtok
的第一次调用使用指向字符串的指针作为其第一个参数:
chk = strtok (line, delims);
而随后所有对strtok
的调用都使用NULL
作为第一个参数:
chk = strtok (NULL, delims);
strtok
的优点是它是为在for
循环格式中解析整个字符串而量身定制的。例如:
for (chk = strtok (line, delims); chk; chk = strtok (NULL, delims))
把它们放在一起,把symbolTblChar[MAX_SYMBOLS]
清理成一个指向char
的指针数组,重新安排一下你的逻辑,提供了下面的例子。我猜测LINE_SIZE
需要什么,MAX_SYMBOLS
需要什么(根据需要调整):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_SIZE 128
#define MAX_SYMBOLS 32
int main (int argc, char **argv) {
char *symbolTblChar[MAX_SYMBOLS] = {NULL};
char line[LINE_SIZE] = {0};
char *chk = NULL;
char delims[] = " n";
int lblCnt = 0;
int t = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (fp != stdin && !fp) {
fprintf (stderr, "error: file open failed '%s'.n", argv[1]);
return 1;
}
printf ("nCollecting Symbols:n");
while (fgets (line, LINE_SIZE, fp))
{
for (chk = strtok (line, delims); chk; chk = strtok (NULL, delims)) {
printf (" Adding %s to symbol tablen", chk);
symbolTblChar[lblCnt] = strdup (chk);
lblCnt++;
/* check for MAX_SYMBOLS */
if (lblCnt == MAX_SYMBOLS) {
fprintf (stderr, "warining: MAX_SYMBOLS limit reached.n");
break;
}
}
}
/* close file if not stdin */
if (fp != stdin) fclose (fp);
/* output */
printf ("nSymbols:n");
for (t = 0; t < lblCnt; t++)
printf(" %sn", symbolTblChar[t]);
/* free allocated memory */
for (t = 0; t < lblCnt; t++)
free (symbolTblChar[t]);
return 0;
}
使用示例输入提供:
$ printf "SPACE n LINE n A1 n A2n" | ./bin/symbltbl
Collecting Symbols:
Adding SPACE to symbol table
Adding LINE to symbol table
Adding A1 to symbol table
Adding A2 to symbol table
Symbols:
SPACE
LINE
A1
A2
注意:你当然可以删除Adding X ...
中间打印行,当你完成它。现在,尽管可能不太明显,但您需要使用strdup
(将其参数分配并复制到新的内存位置)将与添加到symbolTblChar
的每个符号关联的内存free
。你可以看到这发生在main
的末尾。
File Input:注意,您也可以提供输入文件名作为程序的第一个参数,程序将从文件而不是stdin
中读取。例如,输入文件:
$ cat symbols.txt
SPACE
LINE
A1
A2
读取文件
$ /bin/symbltbl symbols.txt
Collecting Symbols:
Adding SPACE to symbol table
Adding LINE to symbol table
Adding A1 to symbol table
Adding A2 to symbol table
Symbols:
SPACE
LINE
A1
A2