我正在使用以下代码将stdin存储到数组中。我最终收到了大量警告和分段错误。
while(fgets(str, 256, stdin)){
size_t count = 0;
char** arr = NULL;
char* token = NULL;
char* delim = ' ';
for(int i=0; i < strlen(str); i++)
if (isspace(str[i])) count++;
count++;
arr = malloc(sizeof(char*) * (count));
for(int i=0; i <= count; i++){
token = strtok(str, delim);
arr[i] = token;
}
for (int i = 0; i < count; ++i)
{
printf("%s\n", arr[i]);
}
//if(strncasecmp(str, "quit", 4) == 0) break;
free(arr);
}
我对编译中的这个警告感到有点困惑
c:34:12: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int'
[-Wint-conversion]
char* delim = ' ';
^ ~~~
最后,当我运行它时,我最终遇到了一个段错误。
admin 123 tyu
Segmentation fault: 11
我在这里做错了什么。
答案 0 :(得分:3)
我注意到了第一个问题。 这不好。
for(int i=0; i <= count; i++){
token = strtok(str, delim);
arr[i] = token;
}
将其替换为以下内容:
token = strtok(str, delim);
while(token){
arr[i] = token;
token = strtok(NULL, delim);
}
strtok
的参考手册表示您在str
上使用它一次,其余时间使用NULL
来连续拆分字符串。查看strtok()
手册页和给定示例以获取简单用法。
第二点是,delim
必须是C字符串,因此在您的情况下,char*
类型将是delim = " "
而不是delim = ' '
。理想情况下,它也应该是const char *delim = " ";
。
答案 1 :(得分:2)
警告是关于这一行:
char* delim = ' ';
通过使用单引号,您创建了一个char而不是字符串。编译器将空间转换为整数并尝试将其分配给指针。当您尝试使用指针时,会出现分段错误。
要解决此问题,您只需将单引号更改为双引号即可。
答案 2 :(得分:1)
单引号用于称为字符常量的东西,它们是所包含字符的ASCII值。
您必须传递给strtok()
的是指向一串分隔符的指针,这些分隔符可能不止一个。
要生成指向字符串的指针,您可以使用字符串文字,但它们不可写,因此您必须小心防止写入它们,一种方法是防止使用const
限定符,那样你的编译器就会发出警告,所以
const char *delim = " ";
更有可能是你想要的。
由于单引号产生一个整数,你的程序会为指针类型分配一个整数,这几乎肯定会导致未定义的行为。
这意味着您没有启用编译器警告,否则编译器会告诉您正在从不兼容的整数类型生成指针。