0

I created a function that checks if a given string is a number or not. The problem is that I take the input with fgets but ,when called, it doesn't stop to take input from user! I tried to fix adding fflush(stdin) and fflush(stdout) to fix because I read some stuffs online but isn't working :S

getInput calls the fgets that stores the string taken from user input then isInt checks if it's an int or not. The problem is that the program stucks on the first fgets.

int isInt (char* string)
{ 
  int k=0;
  while( string[k] != '\0')
  {
    if ( isdigit(string[k])==0) //it's k++ here, I copied bad
      return 1;
  }
  return 0;
}

void getInput(char* string)
{
    printf("Insert a number : \n");
    while (1)
    {
       fflush(stdout); //Tried to fix
       fflush(stdin); //same as above
       fgets(string,sizeof(string),stdin); //stucks here
        if(isInt(string)==0 )
        {
            printf("Ok it's a number!\n");
            break;
        }
        else printf("Insert a valid number!\n");;
    }
}
Finley Adams
  • 773
  • 1
  • 8
  • 20
  • 2
    `while( string[k] != '\0')` - you'll probably want to increment `k` at some point to avoid an infinite loop. `sizeof(string)` is the size of a pointer, and almost certainly not what you want to pass to `fgets`. – Crowman Oct 22 '20 at 14:20
  • Check the return value of `fgets()`. Always check return values of read functions. (`fgets()`, `scanf()`, `fread()`, ...) – 12431234123412341234123 Oct 22 '20 at 14:25
  • @Crowman you're right, I copied bad but the right line was "isdigit(string[k++])", I'll edit – Finley Adams Oct 22 '20 at 18:04

2 Answers2

2
  • fgets() will put newline character read from the stream into the array, so remove that to avoid isInt returning 1 seeing the newline character.
  • sizeof(string) is the size of pointer, not the size of pointed buffer. You will have to receive the size of buffer separately. For more information, see C sizeof a passed array - Stack Overflow.
  • fflush(stdin); invokes undefined behavior, so you shouldn't use that.
  • You have to increment k in the loop in isInt, or it may stuck into an infinite loop. (thanks @Crowman)
#include <string> // for using strchr()

int isInt (char* string)
{ 
  int k=0;
  while( string[k] != '\0')
  {
    if ( isdigit(string[k])==0)
      return 1;
    k++; // increment k
  }
  return 0;
}

void getInput(char* string, size_t string_max) // add parameter to get buffer size
{
    printf("Insert a number : \n");
    while (1)
    {
       fflush(stdout);
       fgets(string,string_max,stdin); // use passed buffer size instead of sizeof()
       char* lf = strchr(string, '\n'); // find newline character
       if (lf != NULL) *lf = '\0'; // and remove that if it exists
        if(isInt(string)==0 )
        {
            printf("Ok it's a number!\n");
            break;
        }
        else printf("Insert a valid number!\n");
    }
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Better to return some indication that the `fgets()` returned `NULL` or not. Useful to avoid UB of `strchr(string, '\n')` when `string` was not populated. – chux - Reinstate Monica Oct 22 '20 at 14:22
  • Very useful thanks Mike! Btw I didn't get these two lines : "char* lf = strchr(string, '\n'); " and " if (lf != NULL) *lf = '\0';" – Finley Adams Oct 22 '20 at 18:11
0

I think that you should put the fgets inside the while condition:

while(fgets(string,sizeof(string),stdin))