5

I'm trying to use gets() to get a string from the user, but the program seems to be passing right over gets(). There is no pause for the user to give input. Why is gets() not doing anything?

char name[13];
printf("Profile name: ");
gets(name);
printf("\n%s", name);
Felix An
  • 309
  • 4
  • 13
Ace
  • 462
  • 4
  • 10
  • 17
  • Have you tried scanf? Also are you sure the input is no more than 12 characters long. What test values have you used? – HopAlongPolly Oct 30 '13 at 18:29
  • 1
    @DerekDrummond 12 characters of input, the last has to be `'\0'`. – Kevin Oct 30 '13 at 18:32
  • 2
    please use `fgets(name, sizeof name, stdin)` instead of `gets()` issue is answered many times see one of the answer http://stackoverflow.com/questions/7231349/getsstring-function-skipping-first-gets-request?rq=1 – Gangadhar Oct 30 '13 at 18:33
  • Good call I forgot about that sentinel character. – HopAlongPolly Oct 30 '13 at 18:33
  • Yes I have used scanf and it works. – Ace Oct 30 '13 at 18:33
  • 2
    Don't use `scanf` for reading strings either. Just use `fgets`. – Kninnug Oct 30 '13 at 18:36
  • @Kninnug If I used scanf previously in my code will fgets still be passed over? – Ace Oct 30 '13 at 18:43
  • 1
    I believe you can leave a white-space at the end of the `scanf` format to make it consume any white-space (such as the trailing new-line) in the input. But don't quote me on that. – Kninnug Oct 30 '13 at 18:53
  • 1
    I tried fgets(name, sizeof name, stdin) but it get passed over. It's sad that gets() used to be so simple and now is replaced by something bulky. – Yan King Yin Feb 20 '16 at 09:28
  • Does this answer your question? [Gets(string#) function skipping first gets request](https://stackoverflow.com/questions/7231349/getsstring-function-skipping-first-gets-request) – IRTFM Nov 21 '22 at 23:02

7 Answers7

7

Call getchar() before you call gets() or fgets(). Since gets() or fgets() is getting skipped due to an already present '\n' from previous inputs in stdin, calling getchar() would lead to itself getting skipped instead of gets() or fgets() or any other similar function. But remember its more of a hack and not a standard solution (I think so), and also use of gets() is forbidden.

        printf("\nEnter a String: ");
        getchar();
        //fgets(inputString, 100, stdin);
        gets(inputString);
        printf("\n%s", inputString);
thisisprateek
  • 136
  • 2
  • 5
4

It's because gets() it's so incredibly dangerous to use, that some C libraries have removed it completely and replaced it with a version that does nothing.

Use fgets() instead.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
3

Use fflush(stdin); before gets()

2

You get lot of troubles using gets()

Instead go for fgets()

fgets(name,13,stdin);  

See this SO question Why is the gets function so dangerous that it should not be used?

The reason why fgets() does not work, may be you are not handling the newline left behind by scanf in your previous statements.

You can modify your scanf format string to take it into account: scanf("%d *[^\n]", &N);

*[^\n] says to ignore everything after your integer input that isn't a newline, but don't do anything with the newline (skip it).

When you use scanf("%d",&num) you hit 13 and enter and 13 is stored in num and the newline character is still in the input buffer when you read fgets from stdin it treats \n as the data you have entered and the fgets() statement is skipped

You cannot flush input buffer however you can do this fseek(stdin,0,SEEK_END); add this before your every fgets statement

Community
  • 1
  • 1
niko
  • 9,285
  • 27
  • 84
  • 131
  • @Andre could you post us your complete code? its working here – niko Oct 30 '13 at 18:44
  • void createProfile() { char name[13]; printf("Profile name: "); fgets(name,13,stdin); printf("\n%s", name); } – Ace Oct 30 '13 at 18:45
  • did u use scanf in any part of your code @Andre because scanf() reads exactly what you ask it to; it's leaving everything else unread, notably the newline following the data. – niko Oct 30 '13 at 18:51
  • Yes I used it a few times earlier. So are you saying I should only use fgets? – Ace Oct 30 '13 at 18:54
  • Suggest `fgets(name, sizeof(name), stdin)`. – chux - Reinstate Monica Oct 30 '13 at 19:38
  • Really don't think you want the space in `scanf("%d *[^\n]",&N);` as it _will_ consume the newline after the integer. – chux - Reinstate Monica Oct 30 '13 at 19:40
  • The asker wants to get a "%s", not "%d". Numbers are easier to handle. I also want to get a string, without the tailing `/n`, and I want to get a null string if the user merely pressed enter. – Yan King Yin Feb 20 '16 at 09:31
1

Take a look at gets() reference

Get string from stdin

Reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file is reached.

The newline character, if found, is not copied into str.

A terminating null character is automatically appended after the characters copied to str.

Notice that gets is quite different from fgets: not only gets uses stdin as source, but it does not include the ending newline character in the resulting string and does not allow to specify a maximum size for str (which can lead to buffer overflows).

So, basically gets() is not only unsafe (can lead to buffer overflows) but also reads what's in the input buffer.

I recommend you to use fgets(), but if you want a quick (and lazy and stupid) solution, just flush the input buffer:

char name[13];
printf("Profile name: ");
fflush(stdin);
gets(name);
printf("\n%s", name);
fvdalcin
  • 1,047
  • 1
  • 8
  • 26
  • 3
    The call to `fflush(stdin)` is undefined behavior in C. – digital_revenant Oct 30 '13 at 18:36
  • You're right, it's meant to be used with output buffers. However, [some](http://msdn.microsoft.com/en-us/library/9yky46tz.aspx) compilers implement `fflush(stdin)` as an extension. It works as expected but it compromises portability. – fvdalcin Oct 30 '13 at 18:44
  • 2
    Yes, however the language standard considers it as undefined behavior. And its use should not be encouraged. – digital_revenant Oct 30 '13 at 18:47
1

Add this below function to your code and enjoy it.

string GetString()
{
   char ch;
   string Line="";

   while(1)
   {
       ch=getchar();

       if(ch=='\n')
          break;
       else
          Line+=ch;
    }

    return Line;
}

This function can effect all Spaces and Backspaces too!!!

PouriaDiesel
  • 660
  • 8
  • 11
0

You might need to discard the rest of the line and move on to the beginning of the next one. You can do:

int c; while((c=getchar()) != '\n' && c != EOF);

This discards the rest of the current line (which might have been partially read with scanf(), etc.) and moves on to the next one.

Although fflush(stdin) might also discard the input, it is non-standard behaviour and discouraged.

You should never ever use gets(myString), as it has been completely removed from the C standard due to how unsafe it is. It doesn't enforce the length of the string, so you can go past the end of the buffer and overwrite other values in RAM, causing a buffer overflow, which can be a security vulnerability. Use fgets(myString, myStringSize, stdin); instead. To get rid of the newline in the resulting string, use myString[strcspn(myString, "\n")] = 0;.

Felix An
  • 309
  • 4
  • 13