【问题标题】:Segmentation fault when printing strtok tokens打印 strtok 令牌时出现分段错误
【发布时间】:2013-12-08 21:58:36
【问题描述】:

我正在尝试使用fgets 从标准输入获取一行用户输入,使用strtok 对其进行标记化,然后打印每个标记以确保它被正确标记化。我的代码如下:

char buffer[256];
char *token;`
fgets(buffer, 256, stdin);
token=strtok(buffer," \n\t()<>|&;");

while(token!=NULL) {
        printf("%s",token);
        count++;
        token = strtok(NULL," \n\t()<>|&;");
}

但是,每当我调用 printf 时,我都会遇到分段错误,我似乎无法弄清楚究竟是什么原因。

【问题讨论】:

  • 我刚刚测试过它,它工作正常。你确定你没有从程序的不同部分得到段错误吗?
  • 仅使用此代码的短程序似乎可以正常工作,而不会出现分段错误。能发个失败的代码sn-p吗?
  • @MartinMajer 将上面的代码放在 main 函数中会在我运行它时导致段错误,无论我输入什么。添加打印以测试故障发生的位置,它似乎在打印令牌的 printf 上,因为在该点之前发生的打印将执行,但在后续打印之前我得到了一个段错误。
  • @user3035026 我相信你,但除非我们能够重现它,否则我们将无法诊断问题。几乎可以肯定,您粘贴的代码不是完全正在运行的代码 - 例如,额外的 ` ` ` 字符和未声明的 count 变量 - 所以看到complete, compilable example 将有助于理解您的程序失败的原因。
  • @qwrrty 看起来我应该像你说的那样粘贴整个程序,这个问题最终只是一个被遗忘的#include

标签: c segmentation-fault printf output strtok


【解决方案1】:

我没有看到您的代码有问题(除了第二行末尾的流浪 `,我认为它不在您的实际代码中)。

但是,这一行:

        printf("%s",token);

将永远不会打印任何换行符,这意味着它永远不会刷新输出缓冲区。因此,如果您稍后在程序中出现分段错误,它可能看起来在您打印第一个标记之前就发生了,仅仅是因为它阻止了输出缓冲区被刷新。

出于调试目的,请尝试将上面的内容更改为:

        printf("%s\n",token);

并查看在段错误之前打印的内容。

【讨论】:

    【解决方案2】:

    好的,我把你的代码改成了完整的程序,cf:

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buffer[256];
        char *token;
        int count = 0;
        fgets(buffer, 256, stdin);
        token=strtok(buffer," \n\t()<>|&;");
    
        while(token!=NULL) {
            printf("%s\n",token);
            count++;
            token = strtok(NULL," \n\t()<>|&;");
        }
        return 0;
    }
    

    当我以原始形式运行它时,它可以工作

    bash $ ./a.out
    the quick brown fox
    thequickbrownfoxbash $ 
    

    虽然当然没有空格或换行符。当我添加\n,(如上面的代码)我得到

    bash $ ./a.out
    the quick brown fox
    the
    quick
    brown
    fox
    bash $ 
    

    现在,请注意,我必须删除您的反引号(我认为这是一个错字),并且我必须声明您的 count 变量,但鉴于它有效。

    据此我推断,您向我们展示的片段周围可能有代码存在错误。

    【讨论】:

    • 我很困惑为什么在阅读了这里的所有 cmets 和答案后我仍然会遇到段错误。然后我重新看了你的,发现我愚蠢地忘记了#include &lt;string.h&gt;
    • 嗯。没有它,它甚至不会为我编译。 (从中你可以推断我必须自己添加它:-)
    • 我觉得它在没有它的情况下也编译有点奇怪。但是在其中添加它可以解决问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多