0

I'm using the following code to store stdin into an array. I end up with a host of warnings and a segmentation fault.

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);

    }

I'm a little confused about this warning in compilation

c:34:12: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int'
      [-Wint-conversion]
        char* delim = ' ';
              ^       ~~~

And ofcourse finally when I run it I end up with a seg fault.

admin 123 tyu
Segmentation fault: 11

What am I doing wrong here.

5
  • 1
    You're assigning a char to a pointer Commented May 24, 2015 at 23:56
  • What @ikegami said. The compiler warns about int because the char is getting promoted. Commented May 24, 2015 at 23:56
  • Just change the single quotes to double quotes. Commented May 25, 2015 at 0:00
  • Fixed that part. Thanks. Commented May 25, 2015 at 0:01
  • 1
    Don't do this for(int i=0; i < strlen(str); i++) , it's way too expensive, do it like this for(int i=0; str[i] != '\0'; i++), every time you call strlen() an equivalent to my suggestion loop is executed. Commented May 25, 2015 at 0:12

3 Answers 3

3

I noticed a first problem here. This is not good.

   for(int i=0; i <= count; i++){

        token = strtok(str, delim);
        arr[i] = token;
    }

Replace it with the following:

    token = strtok(str, delim);
    while(token){
        arr[i] = token;
        token = strtok(NULL, delim);
    }

The reference manual of strtok says that you use it on str once and for the rest use NULL to continuously split the string. Look at the strtok() manual page and the given example for a simple usage.

The second point is that delim has to be a C string so a char* type in your case, will be delim = " " not delim = ' '. Ideally, it should be const char *delim = " "; too.

Sign up to request clarification or add additional context in comments.

3 Comments

Please don't use c++ refrences for c questions.
@iharob no it is not only a c++ but a c and c++ reference site. look carefully the header name you have string.h a c version and cstring.h its c++ version
The URL you gave was cplusplus.com/reference/cstring/strtok/?kw=strtok, and that stipulates that the header is <cstring>, which is strictly a C++ header and not a C header (though it is the C++ cover for the C header <string.h>). You could look at the other site, en.cppreference.com/w/c/string/byte/strtok, for a description of the C strtok(). But any page that documents a C++-only header and does not also have the C header equally prominent is less than entirely desirable in an answer to a C question.
2

The warning is about this line:

char* delim = ' ';

By using single quotes, you have created a char not a string. The compiler converts the space to an integer and tries to assign that to the pointer. When you then try to use the pointer, you get a segmentation fault.

To fix it you can simply change the single quotes to double quotes.

Comments

1

Single quotes are used for something called character constants, they are the ASCII value of the enclosed character.

What you have to pass to strtok() is a pointer to a string of delimiter characters, which could be more than one.

To generate a pointer to a string you can use a string literal, but they are not writeable, so you must be careful to prevent writing to them, one way to prevent that is to use the const qualifier, that way your compiler will warn about that, so

const char *delim = " ";

is more likely what you are looking for.

Since the single quotes produce an integer, your program is assigning an integer to a pointer type, which will almost surely cause undefined behavior.

That means that you did not enable compiler warnings, or else, the compiler will tell you that you are making a pointer from an incompatible integer type.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.