1

I defined an array for strings. It works fine if I define it in such a way the first element is not an empty string. When its an empty string, the next scanf() for the other string stops reading the input string and program stops execution.

Now I don't understand how can defining the array of strings affect reading of input by scanf().

  char *str_arr[] = {"","abc","","","b","c","","",""}; // if first element is "abc" instead of "" then works fine

  int size = sizeof(str_arr)/sizeof(str_arr[0]);

  int i;

  printf("give string to be found %d\n",size);


  char *str;
  scanf("%s",str);
  printf("OK\n");
0decimal0
  • 3,884
  • 2
  • 24
  • 39
KT_admin
  • 233
  • 3
  • 7

3 Answers3

1

Declaring a pointer does not allocate a buffer for it in memory and does not initialize it, so you are trying to dereference an uninitialized pointer (str) which results in an undefined behavior.

Note that scanf will cause a potential buffer overflow if not used carefully when reading strings. I recommend you read this page for some ideas on how to avoid it.

MByD
  • 135,866
  • 28
  • 264
  • 277
  • I understand what you are saying, but passing pointers like this has worked fine for me till now. I will not do this from here on. But what baffles me is that how does initialisation of the array of strings which is str_arr affects the working of scanf. program crashes when its an empty string and works just fine when its non empty. – KT_admin Jul 02 '13 at 08:44
  • The initialization of `str_arr` defines its size, and how much can you put into it, it you initialize it with "hello", it will allocate an array of 6 chars (including null terminator), if you initialize it with "", it will only allocate one character, and so any write to the array will be out of the array boundaries. – MByD Jul 02 '13 at 10:31
  • I complete get that. but i dont get how can it affect the reading of a string into a different character pointer which is str. @Matteo Italia – KT_admin Jul 02 '13 at 18:59
1

Actually, you are getting it wrong my brother. The initialization of str_arr doesn't affect the working of scanf() , it may however seem to you like that but it ain't actually. As described in other answers too this is called undefined behavior. An undefined behavior in C itself is very vaguely defined .

The C FAQ defines “undefined behavior” like this:

Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

It basically means anything can happen. When you do it like this :

char *str;
  scanf("%s",str);

Its an UB. Sometimes you get results which you are not supposed to and you think its working.That's where debuggers come in handy.Use them almost every time, especially in the beginning. Other recommendation w.r.t your program:

  • Instead of scanf() use fgets() to read strings. If you want to use scanf then use it like scanf("%ws",name); where name is character array and w is the field width.
  • Compile using -Wall option to get all the warnings, if you would have used it, you might have got the warning that you are using str uninitialized.

Go on reading THIS ARTICLE, it has sufficient information to clear your doubts.

0decimal0
  • 3,884
  • 2
  • 24
  • 39
0

You are passing to scanf a pointer that is not initialized to anything particular, so scanf will try to write the characters provided by the user in some random memory location; whether this results in a crash or something else depends mostly by luck (and by how the compiler decides to set up the stack, that we may also see as "luck"). Technically, that's called "undefined behavior" - i.e. as far as the C standard is concerned, anything can happen.

To fix your problem, you have to pass to scanf a buffer big enough for the string you plan to receive:

char str[101];
scanf("%100s",str); /* the "100" bit tells to scanf to avoid reading more than 100  chars, which would result in a buffer overflow */
printf("OK\n");

And remember that char * in C is not the equivalent of string in other languages - char * is just a pointer to char, that knows nothing about allocation.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • I understand what you are saying, but passing pointers like this has worked fine for me till now. I will not do this from here on. But what baffles me is that how does initialisation of the array of strings which is str_arr affects the working of scanf. program crashes when its an empty string and works just fine when its non empty. – KT_admin Jul 02 '13 at 08:43