从文件中读取并使用 strtok while 循环时只打印每行的第一个单词

While reading from a file and using strtok while loop only prints first word of each line

我是一名 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);
}

我认为 BlueStrat 是对的。尝试先将 word 复制到 printword,然后将 cat " " 复制到 printword

strcpy(printword, word);
strcat(printword, " ");

@BlueStrat 的评论似乎已经指出了这个问题。

当使用 strtok() 时,您必须始终记住它不分配任何内存,而是 returns 指向原始字符串的指针(插入终止符代替定界符),并维护一个内部指向下一个标记开始的静态指针。那么,假设输入文件的第一行包含

one two three

fgets() 会将其读入您的 line 数组:

       0         1
offset 0123456789012 3
line   one two three[=11=]

第一个strtok()调用returns指向偏移量0处字符的指针,将偏移量3处的字符设置为终止符,并将其内部状态变量设置为指向偏移量处的字符4:

       0         1
offset 012 3456789012 3
line   one[=12=]two three[=12=]
       ^    ^
       |    |
       |    +-- (next)
       +------- word 

然后你 strcatword 的末尾添加一个额外的字符,产生:

       0         1
offset 0123 456789012 3
line   one [=13=]wo three[=13=]
       ^    ^
       |    |
       |    +-- (next)
       +------- word 

现在研究一下。您不仅破坏了第一个标记之后的数据,而且还以内部状态指针指向字符串终止符的方式进行了破坏。当您下次调用 strtok() 时,该函数会发现它位于字符串(字符串)的末尾,并且 returns NULL 表示没有更多标记。

与其操纵危险的令牌,不如将其内容连接到 printword 缓冲区,然后将额外的 space 连接到 that