views:

46

answers:

3

I intend to store strings into an array of pointers to strings and then display them as follows :

char *directions[3]; for(i=0;i<3;i++) scanf("%s",directions[i]); for(i=0;i<3;i++) printf("%s",directions[i]);

but when i run this code ,it gives me segmetation fault ,could someone please correct me?

+1  A: 

All you have is pointers to string. You need to make these pointers point to valid memory locations before you try to read using scanf.

// allocate memory.
for(i=0;i<3;i++)
    directions[i] = (char*)malloc(sizeof(char) * SUITABLE_MAX);

// now read.
for(i=0;i<3;i++)
    scanf("%s",directions[i]);
codaddict
You don't need the cast in standard C. Also, `sizeof(char) == 1` by definition, so that multiplicand is redundant.
dirkgently
+3  A: 

You have an array of size 3 of pointers to characters. These pointers do not point to any valid memory where you could possibly store some of those strings that you are reading in. Trying to write to invalid memory invokes UB. Here, UB manifests in the form of a segmentation fault (most probably because you are trying to write to a location you have no control on).

Try allocating some memory first: Say a big enough buffer to read in an entire line (or the biggest string that you think you are going to encounter). Read in, allocate a direction array member and then copy it out as follows:

char *directions[ 3 ];
const MAX_LINE_SIZE = 256;
char line[ MAX_LINE_SIZE ];

for (size_t nstr = 0; nstr < 3; ++nstr) {
      if (fgets( line, MAX_LINE_SIZE, stdin ) != NULL) {
           directions[ nstr ] = malloc( strlen( line ) );
           strcpy( directions[ nstr ], line );
      }
      printf( "%s\n", directions[ nstr ] );
}
dirkgently
thank you so much for such a great explanation :)
pranay
i also tried to store the strings in a 2-D array ,i.e,char directions[100][15] and can successfully store and print them , but how do i use it in switch case statements? I mean when i do :char *p = dir[i][0];switch(p){ case("North") ...}then i get error that "invalid conversion from char to char* and switch quantity not an integer"
pranay
1) That should work. It is possible that 15 is too small a length for your strings and hence you are getting a crash. Remember that the first dimension (100) is basically the number of strings of length 15 that you have. Did you mean to say 15 strings of length 100? In that case swap the dimension values. 2) You cannot `switch` on strings. The `case` labels must be evaluable at compile time. You can use `integral constant expressions` i.e. integral types and/or enums. For strings you can use the traditional `if`-`else`.
dirkgently
ohk thanks again.
pranay
if fgets returns NULL then the content from line is undefined! malloc(strlen(line)) should crash on strcpy, is must be malloc(strlen(line)+1) !!
@gordongekko: True. The `if` was copy-paste error :P BTW: the size parameter of `fgets` includes the null terminator.
dirkgently
A: 
char *directions[ 3 ];
const MAX_LINE_SIZE = 256;
char line[ MAX_LINE_SIZE ];

for (size_t nstr = 0; nstr < 3 && fgets( line, MAX_LINE_SIZE, stdin ); ++nstr) {
  strcpy(directions[ nstr ] = malloc( strlen( line )+1 ),line);
  puts(directions[ nstr ]);
}