简体   繁体   中英

How to check if input is an integer in C?

I have a problem how to check if the input is really an integer. My simple program below writes quotes if the input is 1 or 2. In all other cases it should print "luj".

My code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

  int cislo;

  printf("ml' nob:\n");
  scanf("%d", &cislo);

  if (cislo == 1) {
    printf("Qapla'\n");
    printf("noH QapmeH wo' Qaw'lu'chugh yay chavbe'lu' 'ej wo' choqmeH may' "
           "DoHlu'chugh lujbe'lu'.\n");
  } else if (cislo == 2) {
    printf("Qapla'\n");
    printf("Qu' buSHa'chugh SuvwI', batlhHa' vangchugh, qoj matlhHa'chugh, "
           "pagh ghaH SuvwI''e'.\n");
  } else {
    printf("luj\n");
  }
}

When the input is 1.5 my program read its as 1. But it should print "luj". In python I would do something like isinstance(cislo, int) . How can I do it in C, please?

This question did not help me: Checking if input is an integer in C

Note that C is not like Python: You want to input a number with a decimal point into a variable whose type is an integer . An integer type variable can only hold integers , so... This number will automatically become an integer and the number behind the dot will not be counted.

So when you trying to insert the value 1.5 into cislo the value is automatically converted to an int value, to 1.


Solution:

#include <stdio.h>

int main(int argc, char** argv) {
    float cislo;
    
    printf("ml' nob:\n");
    
    if (scanf("%f", &cislo) != 1)
        // Problem (Handle it)

    if (cislo == 1) {
        printf("Qapla'\n");
        printf("noH QapmeH wo' Qaw'lu'chugh yay chavbe'lu' 'ej wo' choqmeH may' DoHlu'chugh lujbe'lu'.\n");
    } else if (cislo == 2) {
        printf("Qapla'\n");
        printf("Qu' buSHa'chugh SuvwI', batlhHa' vangchugh, qoj matlhHa'chugh, pagh ghaH SuvwI''e'.\n");  
    } else {
        printf("luj\n");
    }
}

scanf with %d will only read integers - anything that's not an integer won't get read.

Unfortunately, this means you can get partial matches as you've experienced - "1.5" is not an integer, but scanf will read and assign the 1 to cislo and return success.

The way around this is to read the next input as text (not try to read it as an integer or float) and do the conversion separately using a library function like strtol or by doing your own conversion manually. Here's an example using strtol :

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define BUFFER_SIZE 11 // up to 10 digits for a 32-bit int plus sign

/**
 * We don't want to use a naked "%s" in our scanf call, since
 * if the user types in more characters than the buffer is sized
 * to hold, we'll write past the end of the buffer.  You can specify
 * the maximum number of characters to read as part of the "%s" 
 * conversion like "%11s", but unlike with printf you can't specify
 * it with a runtime argument - it has to be hardcoded.
 *
 * We're going to create a format string based on the value of BUFFER_SIZE;
 * when we're done, FMT will expand to "%" "11" "s", which will 
 * be interpreted as "%11s".  
 */
#define EXPAND(x) #x
#define STR(x) EXPAND(x)
#define FMT "%" STR(BUFFER_SIZE)  "s" // Make sure we don't read more characters than the buffer can hold

int main( void )
{
  int cislo = 0;

  char buffer[BUFFER_SIZE+1]; // +1 for string terminator
  if ( scanf ( FMT, buffer ) == 1 )
  {
    /**
     * strtol will take a string representation of an integer
     * like "123" and convert it to the corresponding integer
     * value.  chk will point to the first character in the
     * string that *isn't* part of an integer constant.  If that
     * character isn't whitespace or 0 (the string terminator),
     * then the input is not a properly formed integer.
     */
    char *chk;
    int tmp = strtol( buffer, &chk, 10 );
    if ( !isspace( *chk ) && *chk != 0 )
    {
      fprintf( stderr, "%s is not a valid integer input!\n", buffer );
      return -1;
    }
    
    cislo = tmp;
  }

  printf( "cislo = %d\n", cislo );
  return 0;
}

Examples:

$ ./converter 
123
cislo = 123

$ ./converter
abc
abc is not a valid integer input!

$ ./converter
123c
123c is not a valid integer input!

$ ./converter 
12.3
12.3 is not a valid integer input!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM