2
#include<stdio.h>
#include<conio.h>
main()
{
      int i;
      char c, text[30];
      float f;
      printf("\nEnter Integer : ");
      scanf("%d",&i);
      printf("\nEnter Character : ");
      c = getch();
      printf("\nEnter String:");
      gets(text);
      printf("\nEnter Float:");
      scanf("%f",&f);
      printf("\nInteger : %d",i);
      printf("\nCharacter : %c8",c);
      printf("\nString : %s",text);
      printf("\nFloat : %f",f);
      getch();
}

Why is this simple program not able to read a string using the gets() function? What else should I use to correct it? Well it it worked in Turbo C in my old 32-bit PC but not here...

Earlz
  • 62,085
  • 98
  • 303
  • 499
Ravitheja
  • 142
  • 1
  • 8
  • 2
    DevC++ is [crap](http://www.google.com/webhp?hl=en&tab=ww#hl=en&sclient=psy-ab&q=dev+c%2B%2B+bad) You might try it on a compiler that is from this decade. – Earlz Aug 10 '12 at 18:29
  • Ok dude but that crap is my college's standard compiler i don't know why they use such crap. Really frustrating – Ravitheja Aug 10 '12 at 18:35
  • Please, as a first exercise formulate a proper question title. This one is really not informative and will not help others that come after you. – Jens Gustedt Aug 10 '12 at 19:38
  • Well I wonder if it is DEVC++. I have been wondering that for some time. It is free. My friend bought the Intel C++ compiler and it is incredible but it was also 800.00 dollars. What I am trying to find out is there a good free C++ compiler that a person can download or even buy. – Doug Hauf Mar 28 '14 at 01:30

3 Answers3

3

With some little research, I guess that the problem comes with scanf(). scanf() reads a line without the end of line character '\n' which seems to stay in the buffer and actually red by the next statement.

alternatively you can use fgets() and sscanf() as follows:

To read a character I used:

fgets(text,sizeof(text),stdin);
sscanf(text,"%c",&c); /* or: c = text[0]; */

to read an integer I have used

fgets(text,sizeof(text),stdin);
sscanf(text,"%d",&i);

I had a major problem with gets() in a C course I had (to which DevC++) was advised as a compiler. However, I totally recall I didn't follow the advice and it turned out that the behavior of fgets() is also compiler dependent.

The man page for gets() has this:

BUGS

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Muhammad Farag
  • 426
  • 2
  • 12
  • I also tried the following fgets(text,sizeof(text),stdin) instead of gets(text) – Ravitheja Aug 10 '12 at 18:45
  • mmm! For some reason I feel (not know) that the problem is with the behavior of getch() not fgets() or gets(). I would read a buffer line using fgets() and read the first character in it. I could use the same buffer to read the string right after – Muhammad Farag Aug 10 '12 at 19:00
  • i made this mod for the program **' printf("\nEnter Character : "); fgets(c,sizeof(c),stdin); printf("\nEnter String:"); fgets(text,sizeof(text),stdin);'** – Ravitheja Aug 10 '12 at 19:05
  • Ok! I have been playing with this... still not working... Now, I am removing the scanf() and use fgets() and sscanf() I think it is going to work eventually... – Muhammad Farag Aug 10 '12 at 19:06
  • The prototype for fgets() is char *fgets(char *s, int size, FILE *stream) so it should have "char *s" as a first argument. while "c" is only a character – Muhammad Farag Aug 10 '12 at 19:39
  • 1
    @MuhammadFarag:- fflush is supposed to be used with stdout. http://stackoverflow.com/questions/2187474/i-am-not-able-to-flush-stdin – perilbrain Aug 10 '12 at 20:03
  • @Anon ymous: Thanks, I guess I just got it wrong. I will edit Post – Muhammad Farag Aug 10 '12 at 20:11
3

Scanf or other input parsing functions take only required quantity of characters as specified in the call from stdin and reject others.As a result these rejected values,during next read of stdin enter into the variables along with the newline characters and thus skipping inputs for a few calls.So its better to call a clear routine that cleans stdin and stops garbage entering into other variables.

Although your code is quite vulnerable still it has solution:-

#include<stdio.h>

  int clear()
  {
    while ((getchar())^'\n');    
  }
  int  main()
    {
          int i;
          char c, text[30]={0};
          float f;
          printf("\nEnter Integer : ");
          scanf(" %d",&i);
          printf("\nEnter Character : ");     
          scanf(" %c",&c);    
          printf("\nEnter String:");
      clear();
          gets(text);
          printf("\nEnter Float:");   
          scanf(" %f",&f);    
          printf("\nInteger : %d",i);
          printf("\nCharacter : %c",c);
          printf("\nString : %s",text);
          printf("\nFloat : %f",f);
          getchar();
    }
perilbrain
  • 7,961
  • 2
  • 27
  • 35
2

When you type 42 (or whatever) as the first integer, you actually type three characters: 4, 2 and then the newline character that comes from pressing ENTER. Your first scanf reads an integer, which means that it only reads the 4 and the 2, leaving the newline character in the input buffer.

When your program gets to gets, it reads a the very short line that consists just of that newline character.

You can fix it by reading and throwing away the newline character just after scanf, something like this:

printf("\nEnter Integer : ");
scanf("%d",&i);
while (getchar() != '\n')
    ;
Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75