C语言 strtok()在WSL Ubuntu上工作正常,但在Windows Mingw32上不正常[已关闭]

lf5gs5x2  于 2022-12-26  发布在  Windows
关注(0)|答案(3)|浏览(158)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
4小时前关门了。
Improve this question
下面的代码在Windows Mingw32上有问题,但在WSL Ubuntu上没有。分隔符是(char)32(空格)。

while (!feof(f)){
    if(!fgets(line, LINE_LEN, f) || !*line || !strcmp(line, "\n")) continue;
    word = strtok(line, &delim);
    printf("xd\n");
    while(word){
        //printf("%s\n",word);s
        add_item(h,word);
        word = strtok(NULL, &delim);
        wc++;
    }
    lc++;
}

我曾尝试使用CLion调试代码,变量“line”正确填充了包含空格的给定句子,因此strtok在第一次迭代时不应返回null,但它是. CLion Debug

mec1mxoz

mec1mxoz1#

请将该代码替换为:

// FILE *f presumed to be opened for reading
char line[ 1024 ];
int lc = 0, wc = 0;
while( fgets( line, sizeof line, f ) ) {
    for( char *wp = line; ( wp = strtok( wp, " \n" ) ) != NULL; wp = NULL ) {
        add_item( h, wp ); // unseen in this question.
        wc++;
    }
    lc++;
}

空行可以安全地加载到line中,strtok()将正确处理它们(即:找不到任何词语。)

yvgpqqbh

yvgpqqbh2#

Delim只包含空格字符,不包含\0字符,因此崩溃。

    • 编辑:**

@Joop Eggen在下面对此答案的评论中给出了更详细的答案:
strtok的第二个参数是一个分隔符字符串,如" \t.",因此char delim = ' ';&delim搜索下一个字符,直到字符串结束符'\0'

3zwtqj6y

3zwtqj6y3#

strtok函数期望C字符串作为其第二个参数(指向char的空终止数组的指针。delim可能定义为char delim = ' ';,因此&delim是指向char的指针,但不是C字符串,因为只有一个字符且没有空终止符。代码具有未定义的行为,它可能看起来在某些平台上工作而在其它平台上不工作。
您应该改用字符串" \n"" \t\r\n"作为分隔符字符串。
此外,您应该学习Why is “while( !feof(file) )” always wrong?。循环应该更改为:while (fgets(line, LINE_LEN, f)
以下是修改后的版本:

int parse_file(FILE *f, struct hash_table_t *h) {
    char line[LINE_LEN];
    const char *delim = " \t\r\n";
    int wc = 0, lc = 0;

    while (fgets(line, sizeof line, f)) {
        char *p = line;
        char *word;
        while ((word = strtok(p, delim)) != NULL) {
            add_item(h, word);
            wc++;
            p = NULL;
        }
        lc++;
    }
    return wc;
}

相关问题