C 当从文件读取并使用strtok时,While循环只打印每行的第一个字
我是一名Java程序员,在C语言中测试我的运气。我试图逐行读取一个文件,然后计算每个单词。到目前为止,我还没有幸运地把每一行分成几个字。我能够看到每一行并正确地循环文件,但我的输出只是每一行的第一个字。 我做错了什么C 当从文件读取并使用strtok时,While循环只打印每行的第一个字,c,readfile,fgets,strtok,C,Readfile,Fgets,Strtok,我是一名Java程序员,在C语言中测试我的运气。我试图逐行读取一个文件,然后计算每个单词。到目前为止,我还没有幸运地把每一行分成几个字。我能够看到每一行并正确地循环文件,但我的输出只是每一行的第一个字。 我做错了什么 char printword[1024]= ""; void print() { printf("%s", printword); } main() { FILE* f; errno_t err; err = fopen_s(&f,
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);
}
我认为BlueStrat是对的。尝试先将word复制到printword,然后将cat复制到printword
strcpy(printword, word);
strcat(printword, " ");
@BlueStrat的评论似乎已经将矛头指向了这个问题 在使用strtok时,您必须始终记住它不分配任何内存,而是返回指向原始字符串的指针,插入终止符代替分隔符,并维护指向下一个标记开始的内部静态指针。那么,假设输入文件的第一行包含
one two three
fgets会将其读入线阵列:
第一个strtok调用返回指向偏移量0处字符的指针,将偏移量3处的字符设置为终止符,并将其内部状态变量设置为指向偏移量4处的字符:
0 1
offset 012 3456789012 3
line one\0two three\0
^ ^
| |
| +-- (next)
+------- word
然后在单词的末尾加上一个字符,生成:
0 1
offset 0123 456789012 3
line one \0wo three\0
^ ^
| |
| +-- (next)
+------- word
现在研究一下。您不仅破坏了第一个标记后面的数据,而且还以内部状态指针指向字符串终止符的方式进行了破坏。然后,当您下次调用strtok时,该函数会看到它在字符串的末尾是一个字符串,并返回NULL以表示不再有令牌
与其操纵令牌(这很危险),不如将其内容连接到打印字缓冲区,然后将额外的空间连接到该缓冲区。我认为最内部循环中的strcat调用可能会损害操作。strtok必须小心处理,因为它会在每次连续调用期间修改要标记的字符串。我打赌它不希望在调用之间修改源缓冲区字。您打算如何处理strcat函数调用?printf\n,NULL?如果你只是想让tom在单词后面加一个空格,那就别再考虑那些抄袭和拼凑了。C的字符串与其他语言中的字符串不同;与他们合作有些棘手。如果您想要一个空格,请将其置于printf的格式字符串中。在使用printf%s,word;触发strtok行之前,请重新安装打印函数和循环中的所有内容;。
0 1
offset 0123 456789012 3
line one \0wo three\0
^ ^
| |
| +-- (next)
+------- word