【问题标题】:strtok_r throwing in random new linesstrtok_r 随机插入新行
【发布时间】:2021-05-02 00:01:19
【问题描述】:

大家好,我对strtok_r 随机插入新行有疑问,想知道是否有人可以告诉我为什么会这样做?据我了解,当输入末尾有新行时,它会打印一个新行,但这并不是每次都会发生,我不知道为什么。我的动机是输入一个包含多个单词的字符串,并让strtok_r 将单词单独存储到一个数组(存储)中。

char delimit[] = " \t\r\n\v\f";
char *tempword; //temporary word until it is stored into the temp array
for (int r = 0; r < line_count; r++) {
    int counting = 0; //location of where tempword is stored in temp[counting]
    tempword = strtok_r(ptrarray[r], delimit, &ptrarray[r]);
    while (tempword != NULL && strcmp(tempword,"\n") != 0 && strcmp(tempword, "\0") != 0) {
        printf("temp: %s\n", tempword);
        storage[r][counting] = strdup(tempword); 
        tempword = strtok_r(NULL, " ", &ptrarray[r]);
        counting++;   
    }
    storage[r][word_count] = NULL; //last argument = NULL for execvp function
}

【问题讨论】:

  • 为什么在您对strtok_r() 的调用中会有ptrarray[r] 两次?你看过examples of how to use strtok_r()吗?
  • 在您第一次调用strtok_r() 时,您传递了一个包含多个空格字符(包括换行符)的分隔符字符串。该调用解析的令牌(如果有)将不包含换行符。另一方面,循环内的调用都传递了一个仅包含空格字符的分隔符字符串。这是有效的,但不一定是您真正想要的。除此之外,我们可能需要查看minimal reproducible example 来确定发生了什么。
  • 还要注意,虽然在技术上让strtok_r() 在调用之间重用ptrarray[r] 来转发状态在技术上并没有错,但这很可疑,并且可能会在其他地方引起问题。您当然可以为用于此目的的单个独立指针腾出空间。
  • 非常感谢约翰,我会试试你的建议。

标签: c strtok


【解决方案1】:

strtok_r 的第三个参数应该是 char * 的地址,用于存储下一次调用 strtok_r 的内部状态,并使用 NULL 初始指针返回下一个令牌。您传递了您尝试解析的字符串指针的地址,这是不正确的。您应该传递一个单独变量的地址。

此外,strtok_r 不会返回指向换行符的指针,也不会返回指向空字符串的指针,因此额外的测试是多余的。

最后,您应该为所有标记传递相同的分隔符字符串。

这是修改后的版本:

char delimiters[] = " \t\r\n\v\f";
for (int r = 0; r < line_count; r++) {
    char *tempword; //temporary word until it is stored into the temp array
    char *state;
    int counting = 0; //location of where tempword is stored in temp[counting]
    tempword = strtok_r(ptrarray[r], delimiters, &state);
    while (tempword != NULL) {
        printf("temp: %s\n", tempword);
        storage[r][counting] = strdup(tempword); 
        tempword = strtok_r(NULL, delimiters, &state);
        counting++;   
    }
    storage[r][word_count] = NULL; //last argument = NULL for execvp function
}

【讨论】:

    猜你喜欢
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    相关资源
    最近更新 更多