I have been experiencing problems in using the gets() command in C. Whenever I use it twice followed by scanf for eg:

char name[20],add[20];
printf("Enter name : ");
gets(name);
printf("Enter address :");
gets(add);
printf("Enter age :");
scanf("%d",age);

Here it skips name.(doesnot take input of name!)

It doesnot input both the name and address. It skips one of them and this occurs only when i use scanf also. And "scanf" has problem with spaces so i cant use that for strings. Pls help me out!

U forgot to put the ampersand at age.It should look like this

scanf("%d",&age)

btw,u might wanna declare variable age first.

Never use gets(), it is a totally unsafe function.

Using scanf() comes with it's own bunch of problems as well, not least of which is the behaviour of leaving the newline behind, ready to mess up your gets() calls.

Always use

char buff[BUFSIZ];
fgets( buff, sizeof buff, stdin );

to read a line of input, then use your favourite conversion functions (sscanf, strtod, etc etc) to extract information from the line in the buffer.

Always check the return result of fgets() and conversion functions to ensure your input is good.

What upset me sometimes is that any book or video tutorial that
tries to teach you C programming, all of them teach you to use gets() and scanf() as the default to read input. I understand that is easy for learning but it should be shown what problems you get when using those functions. As a beginner learning, you think everything is well with them. It took me to meet this fine forum to start understanding what was wrong using those functions.

I sugest you to do some search in this forum for the gets() and scanf()
and you will learn why your code has problems not stopping to read the next input from you. ;)

What upset me sometimes is that any book or video tutorial that tries to teach you C programming, all of them teach you to use gets() and scanf() as the default to read input. I understand that is easy for learning but it should be shown what problems you get when using those functions. As a beginner learning, you think everything is well with them. It took me to meet this fine forum to start understanding what was wrong using those functions.

100% agreement; it seems that far too many teachers haven't learned the language that well before instructing others. :(

I sugest you to do some search in this forum for the gets() and scanf() and you will learn why your code has problems not stopping to read the next input from you. ;)

I'll offer some minor assistance (forgive the personal bias):
User Input: Strings and Numbers [C]

@ Dave Sinkula

Your tutorial has been a great help for me. I was going to point to it, but
I don't know how to make it a link to a frase or word. I'm very glad that
you did

try using...
fflush(stdin);
after every gets();

Comments
You really need to learn C before giving any more advice.

> fflush(stdin);
> after every gets();
Great - worst advice of the week award winner :rolleyes:

Thoroughly review the link posted by ~s.o.s~.

I guess you should read with more concentration....

int fflush(FILE* stream);

Flushes stream stream and returns zero on success or EOF on error.

Effect undefined for input stream. fflush(NULL) flushes all output streams.

The effect of fflush is undefined on the input stream as it was always meant for output file streams for forcing the output onto the screen.

Thanx everyone for the response. but whether i use gets or fgets the same problem occurs. It doesnt occur in a simple program but in a more complicated one it does occur.
I tried using both gets and fgets but the problem persists.
and not using the & sign was a typo error.
Pls help, isnt there a simple way to input strings in C without all the fuss. I never had a problem in C++.

Pls help, isnt there a simple way to input strings in C without all the fuss. I never had a problem in C++.

Without a full program that can be run, it's hard to tell you what's wrong without guessing. But if you're having this problem in C, you would also have it in C++ with equivalent code because input is handled in the same way just with different syntax.

The code you posted, is it in a loop? If it is then you're seeing the newline problem that Salem mentioned. If it isn't, you need to post more code. Just because it looks like the problem is with gets() doesn't mean that gets() isn't being affected by the code around it. Or more specifically, the code prior to it that makes changes to the input stream.

thnx Ravalon,
ok heres the code in which it isnt working. I might sound stupid but by making certain manipulations this program sometimes works and sometimes doesnt work! This one does NOT work. It skips the input of address.( only name and age are taken input)

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     scanf("%d",&age);
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

thnx Ravalon,
ok heres the code in which it isnt working. I might sound stupid but by making certain manipulations this program sometimes works and sometimes doesnt work! This one does NOT work. It skips the input of address.( only name and age are taken input)

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     scanf("%d",&age);
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

Okay, now we're getting somewhere. :) The problem really is the newline thing that Salem was talking about. When you use scanf() to read an int and then try to use gets(), it looks like gets() is skipped. It isn't really skipped, it just ends right away because scanf() leaves a '\n' in the stream and gets() is designed to stop when it reads '\n'.

The same problem exists in C++.

#include <iostream>


int main()
{
  using namespace std;

  char name[20];
  char addr[20];
  int age;

  cout << "Please enter your name: ";
  cin.getline( name, sizeof name );

  cout << "Please enter your age: ";
  cin >> age;

  cout << "Please enter your address: ";
  cin.getline( addr, sizeof addr );

  cout << "Your name is " << name
    << "\nYour address is " << addr
    << "\nYour age is " << age << '\n';

  return 0;
}

There are a few ways to fix it, but the easiest is to just move your age retrieval so that it's last. :)

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter address : ");
     gets(add);
     printf("\nEnter age: ");
     scanf("%d",&age);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

If you can't do that, you need to either clean up the input stream after calling scanf(), or avoid scanf() entirely and always use gets() to read from stdin. Then you can use sscanf() to parse.

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     char buff[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     gets(buff);
     sscanf(buff,"%d",&age);
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

That's the better option. You can clean up the stream by reading until you get to '\n', or by using fflush( stdin ) with the caveat that it's a really bad idea. ;)

#include<conio.h>
#include<stdio.h>


void flush_stdin( void )
{
  int ch;

  do
    ch = getchar();
  while ( ch != EOF && ch != '\n' );
}


void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     scanf("%d",&age);
     flush_stdin();
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

And I would probably get in trouble if I didn't mention that void main() and gets() are both wrong. It should be int main( void ) with a return value of 0 for success, and fgets(). ;)

Not to forget that getch() is not a standard function, some compiler support it, some don't. Use the portable equivalent getchar() to achieve the same purpose.

Okay, now we're getting somewhere. :) The problem really is the newline thing that Salem was talking about. When you use scanf() to read an int and then try to use gets(), it looks like gets() is skipped. It isn't really skipped, it just ends right away because scanf() leaves a '\n' in the stream and gets() is designed to stop when it reads '\n'.

The same problem exists in C++.

#include <iostream>


int main()
{
  using namespace std;

  char name[20];
  char addr[20];
  int age;

  cout << "Please enter your name: ";
  cin.getline( name, sizeof name );

  cout << "Please enter your age: ";
  cin >> age;

  cout << "Please enter your address: ";
  cin.getline( addr, sizeof addr );

  cout << "Your name is " << name
    << "\nYour address is " << addr
    << "\nYour age is " << age << '\n';

  return 0;
}

There are a few ways to fix it, but the easiest is to just move your age retrieval so that it's last. :)

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter address : ");
     gets(add);
     printf("\nEnter age: ");
     scanf("%d",&age);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

If you can't do that, you need to either clean up the input stream after calling scanf(), or avoid scanf() entirely and always use gets() to read from stdin. Then you can use sscanf() to parse.

#include<conio.h>
#include<stdio.h>
void main()
{
     char name[20],add[20];
     char buff[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     gets(buff);
     sscanf(buff,"%d",&age);
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

That's the better option. You can clean up the stream by reading until you get to '\n', or by using fflush( stdin ) with the caveat that it's a really bad idea. ;)

#include<conio.h>
#include<stdio.h>


void flush_stdin( void )
{
  int ch;

  do
    ch = getchar();
  while ( ch != EOF && ch != '\n' );
}


void main()
{
     char name[20],add[20];
     int age;
     printf("\nEnter name : ");
     gets(name);
     printf("\nEnter age: ");
     scanf("%d",&age);
     flush_stdin();
     printf("\nEnter address : ");
     gets(add);
     printf("\n\n\nName is %s",name);
     printf("\n\nAddress is %s",add);
     printf("\n\nAge is %d",age);
     getch();
}

And I would probably get in trouble if I didn't mention that void main() and gets() are both wrong. It should be int main( void ) with a return value of 0 for success, and fgets(). ;)

Hurray! Thanx a lot Ravalon you finally helped me out! The sscanf() method is the one I used. This problem had me stuck for quite a while...thnx again!!!:)
And i definitely will take your advice on getch() and void main() and fgets().
One more thing, plz tell why is it preferrable to use int main(void) and return 0 rather than simply void main() . thnks a lot

Hurray!

Yay! Everybody cheer now! :)

One more thing, plz tell why is it preferrable to use int main(void) and return 0 rather than simply void main() . thnks a lot

void main() isn't legal C unless your compiler allows it as an extension. Not all compilers allow it as an extension, and that makes void main() dangerously nonportable because if it's not supported, the entire program no longer has predictable behaviour.

That's the theory at least. The only proof I've seen that void main() breaks hard has been on obscure and ancient machines. ;)

One more thing, plz tell why is it preferrable to use int main(void) and return 0 rather than simply void main() . thnks a lot

Because that is what the C standard says.. ;)

There are only two correct prototypes for main( ) :

  • int main( void )
  • int main( int argc, char* argv[] )

And only three valid values which main can return:

  • return 0
  • return EXIT_SUCCESS
  • return EXIT_FAILURE

Anything else is implementation / platform dependent and may make your code non portable.

So in the end the whole hassle is about keeping your programs portable and makign sure that a standard exists which every C / C++ developer follows.

This document describes the problems pretty well.
http://users.aber.ac.uk/auj/voidmain.shtml

In short, it's not guaranteed to compile on other systems (already mentioned), can cause stack problems because the number returned is so large, and it can make operating systems and scripts think that the program crashed.

Is there really any reason to use void main() anyway? No.

Is there really any reason to use void main() anyway? No.

Well, yes. :) The problem is with hosted programs, where your program runs on top of a controlling program like an OS. That's where the rules for main apply. In a freestanding program, where your program is the controlling program, all bets are off.

But if you're writing a freestanding program, you probably don't need to be told the rules. :)

Well, yes. :) The problem is with hosted programs, where your program runs on top of a controlling program like an OS. That's where the rules for main apply. In a freestanding program, where your program is the controlling program, all bets are off.

But if you're writing a freestanding program, you probably don't need to be told the rules. :)

But whats a freestanding program?Isnt every program run on top of a controlling program( i.e. OS )? Or do you mean writing an OS itself?

and is return 0 used because it returns the value 0 to OS that means that the program ran successfully

Or do you mean writing an OS itself?

That's what I understand.

and is return 0 used because it returns the value 0 to OS that means that the program ran successfully

Yeah, although some oddball operating systems don't always use 0 as success value, so using EXIT_SUCCESS and EXIT_FAILURE are the only portable ways to guarantee that your program returns the correct exit code.

But whats a freestanding program?Isnt every program run on top of a controlling program( i.e. OS )? Or do you mean writing an OS itself?

Look around you. No. No.

Your car. Your TV. Your thermostat.

Most code is actually written for freestanding implementations, so we must give it a bit of credit for being there.

Look around you. No. No.

Your car. Your TV. Your thermostat.

Most code is actually written for freestanding implementations, so we must give it a bit of credit for being there.

What you write is definitely correct. But dont you think C/C++ programming is mostly OS and platform dependent. So considering what developing and programming we all are doing, its always dependent on a controlling program. In general, definitely, if there was no freestanding programming then there would be no controlled programming
Its always better to have a standard and I thank you guys of making me aware of that.
void main()'ers are definitely doomed!:)

That's what I understand.

That's essentially what I meant too. :) But when I think of an OS, I think of something more sophisticated than most freestanding programs that are just a simple controller for hardware in embedded chips. But they do fit the definition of an OS, so I can't argue the point without being wrong. ;)

Yeah, although some oddball operating systems don't always use 0 as success value, so using EXIT_SUCCESS and EXIT_FAILURE are the only portable ways to guarantee that your program returns the correct exit code.

If the OS doesn't actually use 0 internally for a success value, the compiler has to somehow turn return 0; into return [I]whatever the OS expects for success[/I]; . That's a language requirement.

If the OS doesn't actually use 0 internally for a success value, the compiler has to somehow turn return 0; into return [I]whatever the OS expects for success[/I]; . That's a language requirement.

So does C/C++ do that? That means we always use return 0 to return the value to the OS so that the OS understands that the program run was a success. And it must be portable to use return 0 i think

So does C/C++ do that? That means we always use return 0 to return the value to the OS so that the OS understands that the program run was a success. And it must be portable to use return 0 i think

Yeah, C/C++ does that. When you return 0 from main(), it always means success. :)

The easiest way to get rid of gets() problem is to repeat that particular gets(); line

The Solution

#include<stdio.h>
    void main()
    {
    char name[20],add[20];
    int age;
    printf("\nEnter name : ");
    gets(name);
    printf("\nEnter age: ");
    scanf("%d",&age);
    printf("\nEnter address : ");
    gets(add);  
    gets(add);  //repeat gets(); 
    printf("\n\n\nName is %s",name);
    printf("\n\nAddress is %s",add);
    printf("\n\nAge is %d",age);
    getch();
    }
Comments
Fail on so many levels.
This question has already been answered. Start a new discussion instead.