用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; }
我对编程非常陌生,但我试着编写一个函数,从用户输入的字符串中提取单词,并将它们保存在数组中,以便以后在程序中使用。我添加了两行printf代码,看看它是否工作正常。 在while循环的第二次迭代之后,我总是得到一个分段错误。用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
此外,当我在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
时仍然为零,因此没有为数组分配空间。