我是一名Java程序员,在C测试我的运气。我正在尝试逐行读取文件,然后计算每个单词。到目前为止,我没有运气将每一行分成单词。我能够看到每一行并正确循环文件,但我的输出只是每行的第一个单词。 我在这里做错了什么?
char printword[1024]= "";
void print() {
printf("%s", printword);
}
main()
{
FILE* f;
errno_t err;
err = fopen_s(&f, FILE_NAME, "r");
if (&f == NULL) {
exit(EXIT_FAILURE);
}
char line[1024];
while (fgets(line, 1024, f) != NULL) {
char * word;
char *context = " ";
word = strtok(line, " ");
while (word != NULL) {
strcpy(printword, strcat(word," "));
print();
word = strtok(NULL, " ");
}
printf("\n", NULL);
}
//}
fclose(f);
printf("Press any key to continue");
getchar();
exit(0);
}
答案 0 :(得分:1)
@BlueStrat似乎已将他的评论放在了这个问题上。
使用strtok()
时,必须始终记住它没有分配任何内存,而是返回指向原始字符串的指针(插入终结符代替分隔符),并维护一个指向开头的内部静态指针下一个标记。那么假设输入文件的第一行包含
one two three
fgets()
会将其读入您的line
数组:
0 1
offset 0123456789012 3
line one two three\0
第一个strtok()
调用返回指向偏移0处字符的指针,将偏移量为3的字符设置为终结符,并将其内部状态变量设置为指向偏移量为4的字符:
0 1
offset 012 3456789012 3
line one\0two three\0
^ ^
| |
| +-- (next)
+------- word
然后你strcat
在word
的末尾添加一个额外的字符,产生:
0 1
offset 0123 456789012 3
line one \0wo three\0
^ ^
| |
| +-- (next)
+------- word
现在研究一下。您不仅在第一个令牌之后损坏了数据,而且还是以内部状态指针指向字符串终止符的方式完成了。当您下次调用strtok()
时,该函数会看到它位于字符串的末尾(字符串),并返回NULL
以表示没有其他标记。
而不是操纵危险的令牌,而是将其内容连接到printword
缓冲区,然后将额外的空间连接到那个。
答案 1 :(得分:0)
我认为BlueStrat是对的。尝试先将word复制到printword,然后将cat“”复制到printword
strcpy(printword, word);
strcat(printword, " ");