将来自stdin的输入存储在C中的数组中

时间:2015-05-24 23:54:52

标签: c arrays

我正在使用以下代码将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

我在这里做错了什么。

3 个答案:

答案 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 = " ";

更有可能是你想要的。

由于单引号产生一个整数,你的程序会为指针类型分配一个整数,这几乎肯定会导致未定义的行为

这意味着您没有启用编译器警告,否则编译器会告诉您正在从不兼容的整数类型生成指针。