用strtok实现C程序分段故障 #包括 #包括 内部主(空) { int n_of_单词=0; #定义MAX_STR_SZ 256 //请求用户输入 字符串[50]; printf(“\n请输入一个文本字符串。\n\n”); fgets(字符串、最大长度、标准长度); 字符*单词[n个单词中的n个]; //提取第一个单词 单词[n_of_单词]=strtok(字符串“”); printf(“\n%i%s\n”,n个单词,单词[n个单词]; //循环遍历字符串以提取所有其他单词 while(单词[n个单词]!=NULL) { n_of_words++; 单词[n_of_单词]=strtok(空,“”); printf(“\n%i%s\n”,n个单词,单词[n个单词]; } 睡眠(10); 返回0; }

用strtok实现C程序分段故障 #包括 #包括 内部主(空) { int n_of_单词=0; #定义MAX_STR_SZ 256 //请求用户输入 字符串[50]; printf(“\n请输入一个文本字符串。\n\n”); fgets(字符串、最大长度、标准长度); 字符*单词[n个单词中的n个]; //提取第一个单词 单词[n_of_单词]=strtok(字符串“”); printf(“\n%i%s\n”,n个单词,单词[n个单词]; //循环遍历字符串以提取所有其他单词 while(单词[n个单词]!=NULL) { n_of_words++; 单词[n_of_单词]=strtok(空,“”); printf(“\n%i%s\n”,n个单词,单词[n个单词]; } 睡眠(10); 返回0; },c,segmentation-fault,cs50,strtok,C,Segmentation Fault,Cs50,Strtok,我对编程非常陌生,但我试着编写一个函数,从用户输入的字符串中提取单词,并将它们保存在数组中,以便以后在程序中使用。我添加了两行printf代码,看看它是否工作正常。 在while循环的第二次迭代之后,我总是得到一个分段错误。 此外,当我在CS50 ide(Cloud9)上编译相同的代码时,不知何故,这个问题并没有出现,但在任何其他情况下都会发生。有一些问题可能会导致seg故障。首先,我在编译代码时收到警告: #include <stdio.h> #include <unistd

我对编程非常陌生,但我试着编写一个函数,从用户输入的字符串中提取单词,并将它们保存在数组中,以便以后在程序中使用。我添加了两行printf代码,看看它是否工作正常。 在while循环的第二次迭代之后,我总是得到一个分段错误。
此外,当我在CS50 ide(Cloud9)上编译相同的代码时,不知何故,这个问题并没有出现,但在任何其他情况下都会发生。

有一些问题可能会导致seg故障。首先,我在编译代码时收到警告:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    int n_of_words = 0;
    #define MAX_STR_SZ 256

    // asking for user input
    char string[50];
    printf("\nPlease input a string of text.\n\n");
    fgets(string, MAX_STR_SZ, stdin);

    char * words[n_of_words]; 

    // extracting the first word
    words[n_of_words] = strtok(string, " ");
    printf("\n%i  %s\n", n_of_words, words[n_of_words]);

    // looping through the string to extract all other words
    while( words[n_of_words] != NULL )
    {
        n_of_words ++;
        words[n_of_words] = strtok(NULL, " ");
        printf("\n%i  %s\n", n_of_words, words[n_of_words]);
    }
    sleep(10);
    return 0;
}

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    int n_of_words = 0;
    #define MAX_STR_SZ 256

    // asking for user input
    char string[MAX_STR_SZ];  // <--- Use macro to define buffer size
    printf("\nPlease input a string of text.\n\n");
    fgets(string, sizeof string, stdin);

    char * words[MAX_STR_SZ]; // <--- Should never be more words than characters in the buffer

    // extracting the first word
    words[n_of_words] = strtok(string, " ");
    printf("\n%i  %s\n", n_of_words, words[n_of_words]);

    // looping through the string to extract all other words
    while( words[n_of_words] != NULL )
    {
        n_of_words ++;
        words[n_of_words] = strtok(NULL, " ");
        printf("\n%i  %s\n", n_of_words, words[n_of_words]);
    }
    sleep(10);
    return 0;
}
所有这些都是因为您没有为
strtok
包含正确的头,即
string.h
。这可能会导致问题,因为默认返回类型假定为
int
,它可能不够大,无法容纳指针

其次,您向
fgets()
传递的大小不正确。大小应该是用于保存结果的缓冲区的大小。如果缓冲区溢出,将导致未定义的行为

最后,
words
数组声明为大小
n\u of_words
,此时为零。这将导致一个大小为零的数组。C中的数组不会自动增长

以下是已修复这些问题的代码:

../main.c: In function 'main':
../main.c:17:25: warning: implicit declaration of function 'strtok' [-Wimplicit-function-declaration]
     words[n_of_words] = strtok(string, " ");
                         ^~~~~~
../main.c:17:23: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     words[n_of_words] = strtok(string, " ");
                       ^
../main.c:24:27: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
         words[n_of_words] = strtok(NULL, " ");
#包括
#包括
#包括
内部主(空)
{
int n_of_单词=0;
#定义MAX_STR_SZ 256
//请求用户输入

字符字符串[MAX_STR_SZ];//可以解决的几个问题,以防止出现
分段错误

  • strtok
    函数的源代码中没有
    string.h
  • #包括
    #包括
    
  • 宏通常在源代码的顶部声明,而不是在任何函数中声明
  • #定义MAX_STR_SZ 256

  • char string
    数组的长度为
    50
    ,但
    fgets
    允许
    256
    并可能导致缓冲区溢出
  • char字符串[50];
    printf(“\n请输入一个文本字符串。\n\n”);
    fgets(字符串、最大长度、标准长度);
    
  • 变量
    n\u of_words
    的值是
    0
  • char*单词[n个单词];

    不会创建所需长度的数组

  • 你的问题的根本原因在于:
  • while(单词[n个单词]!=NULL)
    {
    n_of_words++;
    单词[n_of_单词]=strtok(空,“”);
    printf(“\n%i%s\n”,n个单词,单词[n个单词];
    }
    
    您正在访问一个从未声明过的内存位置

    n个单词++;
    words[n_of_words]=strtok(NULL,“”;//从未声明words[1]或任何索引。
    

    每个C程序都免费获得一个命令行参数列表,通常声明为
    intmain(intargc,char*argv[]);
    intmain(intargc,char**argv);

    这正是您试图用
    int n_of_words
    char*words[n_of_words];

    但你做得不对

    代码中这三行的第一个注释:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
        int n_of_words = 0;
        #define MAX_STR_SZ 256
    
        // asking for user input
        char string[50];
        printf("\nPlease input a string of text.\n\n");
        fgets(string, MAX_STR_SZ, stdin);
    
        char * words[n_of_words]; 
    
        // extracting the first word
        words[n_of_words] = strtok(string, " ");
        printf("\n%i  %s\n", n_of_words, words[n_of_words]);
    
        // looping through the string to extract all other words
        while( words[n_of_words] != NULL )
        {
            n_of_words ++;
            words[n_of_words] = strtok(NULL, " ");
            printf("\n%i  %s\n", n_of_words, words[n_of_words]);
        }
        sleep(10);
        return 0;
    }
    
    
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    int main(void)
    {
        int n_of_words = 0;
        #define MAX_STR_SZ 256
    
        // asking for user input
        char string[MAX_STR_SZ];  // <--- Use macro to define buffer size
        printf("\nPlease input a string of text.\n\n");
        fgets(string, sizeof string, stdin);
    
        char * words[MAX_STR_SZ]; // <--- Should never be more words than characters in the buffer
    
        // extracting the first word
        words[n_of_words] = strtok(string, " ");
        printf("\n%i  %s\n", n_of_words, words[n_of_words]);
    
        // looping through the string to extract all other words
        while( words[n_of_words] != NULL )
        {
            n_of_words ++;
            words[n_of_words] = strtok(NULL, " ");
            printf("\n%i  %s\n", n_of_words, words[n_of_words]);
        }
        sleep(10);
        return 0;
    }
    
    您正在将256设置为
    fgets()
    的读取限制,但字符串中只有50个字符。在这种情况下,很多时候它都会起作用,因为您是从键盘读取的,我们中的许多人输入的单词都不会超过几个,但您遇到了一个问题。请更改限制

    strtok()
    可能不是这里最好的选择。使用
    scanf()
    的单个循环可以读取许多行,然后用跳过新行之类的文字来打断所有行,您可能会发现编写代码更容易

    无论如何,回到您的代码:由于您事先不知道字数,您可以估计限制为字符串逐个分配内存,甚至以块的形式分配内存。但是

    您需要为将出现SegFault的字符串分配内存 此时,您尝试在
    words[]
    数组中写入

    我更改了您的代码的最小值,以便您可以看到一个示例,并且我固定了
    #define
    中的字符串数,与您目前编写的类似

    一个简单的方法是将--C在
    main()
    --
    words[]
    中声明为
    char**
    并在您知道至少有一个字符串要记录时立即为它们分配内存

    但是你需要注意的是,你只有指针,它们仍然没有指向任何东西

    一旦有一个字符串要加载,您就需要为它分配内存,加上一个字节用于终止
    '\0'
    ,然后复制该字符串并将地址保存在
    words[]
    数组中相应的指针中

    请参阅代码

    #define MAX_STR_SZ 256
    
    char string[50];
    
    fgets(string, MAX_STR_SZ, stdin);
    

    传递给
    fgets
    的大小比缓冲区大得多。这是自找麻烦。
    n\u单词
    在声明
    words
    时仍然为零,因此没有为数组分配空间。