Search code examples
cstringnewlinefgetsgets

gets() not asking for input unless getchar() or another gets() is used before it


i made a c source file 'functions.c' which contains some functions, a header file 'functions.h' containing prototypes of the functions, and a 'main.c' source file. Now i am using main to call functions in functions.c using the prototypes in functions.h. Below is a function from 'functions.c' file.

my code:

#include "functions.h"
#include <stdio.h>
#include <string.h>

void func1(void)
{
  int i, j, k, l;
  char string[25];
  printf("Enter any valid 10 digit mobile number\n");
  here:
  //getchar();
  gets(string);

  j = k = 0;
  for (i = 0; string[i] != '\0';)
  {
    if (string[i] <= 57 && string[i] >= 48)
      i++;
    else if (string[i] == 45 || string[i] == 46 || string[i] == 47 || string[i] == 42 || string[i] == 95 || string[i] == 124 || string[i] == 58 || string[i] == 92 || string[i] == 59 || string[i] == 0)
    {
      i++;
      k++;
    } //some special characters allowed
    else
    {
      printf("%c is not a valid digit or symbol for a mobile number\n", string[i]);
      j++;
      i++;
    }
  }
  if ((i - k) == 10 && j == 0)
    printf("Mobile number is valid\n");
  if ((i - k) != 10 || j != 0)
  {
    printf("Mobile number is invalid\nEnter 1 to try again or 2 to exit\n");
    scanf("%d", &l);
    if (l == 1)
    {
      printf("Enter mobile number again\n");
      goto here;
    }
    else if (l == 2)
      printf("Program Terminating\n");
    else
      printf("You didn't enter either of 1 or 2\nProgram Terminating\n");
  }
}

Now my questions are -

1-"Why is gets() not working? Why is gets() not asking for any input?"

2-"Why does it start asking for input when i include getchar() in the code? I mean when i remove the comment sign from the getchar()?"

I am a newbie.. so please go soft.. thanks for answers.


Solution

  • The problem is your mixed use of scanf and gets: When you use scanf to read a number, the newline the user presses will be in the input buffer, and the scanf call will not remove it. However when you loop back to call gets (by the way, don't use labels and goto for loops!) the gets call reads that newline and sees it as an empty line.

    After scanf you should read characters in a loop until you have read the newline.


    Important note: You might see some places that uses fflush(stdin) to "flush" the input buffer (i.e. discard all to (and including) the newline). This is technically undefined behavior according to the C specification. Some environments have it as an extension, but if you want to be correct and portable you should not use it.