c - 尽管没有到达字符串的末尾,strtok 返回 NULL

标签 c

我正在编写一个程序来解析来自标准输入的输入并根据输入调用函数。 我的程序应该处理的输入如下:

end //stops the program
report //prints a specific output
addent "ent_id"
delent "ent_id"
addrel "ent_id1" "ent_id2" "rel_id"
delrel "ent_id1" "ent_id2" "rel_id"

输入调用的函数与我的问题无关,但请注意传递给函数的所有参数都在引号内。

这是代码

int main() {
    const char Comando[6][7] = { "addrel", "addent", "delrel", "delent", "report", "end" };
    const char spazio[2] = " ";
    const char newline[3] = "\n";
    const char quote[2] = "\"";
    char sample[100];
    char *temp;
    char *comandoIN;
    char *argomento1;
    char *dest;
    char *rel;

    RelHead = NULL;
    init_array();

    char *str = fgets(sample, 100, stdin);

    for (;;) {
        if (strncmp(sample, Comando[5], 3) == 0) {
            return 0;
        } else if (strncmp(sample, Comando[4], 6) == 0) {
            report();
        } else {
            temp = strtok(sample, newline);
            comandoIN = strtok(temp, spazio);
            argomento1 = strtok(NULL, quote);

            if (strncmp(Comando[1], comandoIN, 7) == 0) {
                addent(argomento1);
            } else if (strncmp(Comando[3], comandoIN, 7) == 0) {
                delent(argomento1);
            } else {
                temp = strtok(NULL, quote);
                dest = strtok(NULL, quote);
                temp = strtok(NULL, quote);
                rel = strtok(NULL, quote);

                if (strncmp(Comando[0], comandoIN, 7) == 0) {
                    addrel(argomento1, dest, rel);
                } else if (strncmp(Comando[2], comandoIN, 7) == 0) {
                    delrel(argomento1, dest, rel);
                }
            }
        }

        char *str = fgets(sample, 69, stdin);
    }
    return 0;
}

不正确的行为是由以下输入引起的:

addrel "The_Ruler_of_the_Universe" "The_Lajestic_Vantrashell_of_Lob" "knows"

这导致 strtok 的最后两次调用返回 NULL 而不是 ""(空白)和 "knows" 分别(不带引号)。 此外,如果这是给程序的第一个输入,它的行为是正确的,如果是最后一个,下一个循环将把 "knows" 放入 "comandoIN"多变的。这是迄今为止我发现的导致此问题的唯一输入,我认为这与第一次调用 strtok 时删除换行符有关。

这是 uni 的作业,所以我们有几个输入来测试程序,我的程序通过了其中的前 4 个(每个测试大约有 200 个输入),所以我真的不明白是什么导致了这个错误.有什么想法吗?

最佳答案

这里的问题是输入:

addrel "The_Ruler_of_the_Universe" "The_Lajestic_Vantrashell_of_Lob" "knows"    

是 77 个字节长(76 个字符加上终止 NULL)。

在你的循环结束时你有:

char *str = fgets(sample, 69, stdin);

你说你的缓冲区是 69 长的地方。

如果它是第一个输入,为什么它会正确运行?

在 for 循环之前你有:

char *str = fgets(sample, 100, stdin);
for(;;)
...

此处使用的大小为 100,因此如果您在启动程序后直接使用上述输入即可。

关于c - 尽管没有到达字符串的末尾,strtok 返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57525219/

相关文章:

java - JNI 引用表溢出 : how to release ObjectArray containing Strings

C HTTP Proxy,浏览器无限期显示 "waiting for"

我可以使用它的地址从另一个编译单元调用静态函数吗?

c - strcat 给我一个段错误

c - getchar() != EOF

c++ - Mozilla C/C++ 编码风格

c++ - 无法在 CLion 中运行简单程序

c - 具有一些私有(private)操作的不透明结构

c - 如何使用函数推进数组基地址?

c - LLDB "step in"和 "finish"获取标准函数的返回值