0
#include <stdio.h>

int main()
{
   char text[100];
   int length = 0;

   gets(text);

   while (text[length] != '\0')
      length++;

   printf("%d",length);
}

I was trying to count the letters in an string using the above program. it worked. But, when i tried the same program with scanf() instead of gets(), it didn't work.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
Naseef AR
  • 1
  • 1

1 Answers1

1

gets(buf) and scanf("%[^\n]", buf) are equivalent and MUST NOT BE USED because they will read input beyond the end of buf.

Use fgets(buf, sizeof buf, stdin) and adjust you code for the fact that fgets stores the '\n' at the end of buf if present in the input stream.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • `scanf("%99[^\n]", buf)` is perfectly safe if the definition was `char buf[100];` – pmg Feb 27 '15 at 21:17
  • 1
    That true, but it is very cumbersome to use the size limitation for buffers with a non trivial size, such as `buf[BUFSIZ]`. Not to mention the lack of similarity between `99` and `100` which prevents peripheral vision checks. It is really too bad the specifier syntax for `scanf` is inconsistent with that of `printf`. It should have been: `scanf("%*s", (int)sizeof(buf), buf);` but history cannot be rewritten. – chqrlie Feb 27 '15 at 21:26
  • @pmg `gets()` fails is the input is too long. `scanf("%99[^\n]", buf)` fails if the input is too short - only `'\n'`. – chux - Reinstate Monica Feb 27 '15 at 21:47
  • @chux: `scanf("%99[a]", ...)` means "scan **up to** 99 a's" – pmg Feb 27 '15 at 21:49
  • `scanf("%99[a]", ...)` actually matches a **non-empty** sequence of up to 99 `'a'` characters. chux is right, `scanf` cannot match `gets` function exactly, both are mostly misunderstood. – chqrlie Feb 27 '15 at 22:26
  • @chux: Where "fails" means "exhibits undefined behavior with arbitrarily bad consequences but no required error detection". – Keith Thompson Feb 27 '15 at 22:29
  • 1
    I guess it `scanf("%99[^\n]", buf)` returns 0 on an empty input line and leaves `buf` untouched. If `buf` is uninitialized, its contents are indeterminate and undefined behaviour may ensue if `scanf`s return value is not tested and `buf` is used carelessly. – chqrlie Feb 27 '15 at 22:35
  • @pmg The shortcoming of `scanf("%99[a]", ...)` is that is scans `1` up to `99` a's and not **up to** 99 a's. If input does not begin with `a`, then `buf` does not take on the value of `""`, instead, it is left as is. – chux - Reinstate Monica Feb 27 '15 at 23:28
  • yes!!! Always check the return value: `if (scanf(...) != ) /* error */;` – pmg Feb 28 '15 at 08:29