if you type "123e1" in the command line, the system may read "123" and save the value.

but how can we tell the computer that it's an wrong input?:-|

Dani AI

Generated

's example "123e1" shows the core problem: a plain numeric read can produce a usable value (123) while leaving trailing junk (the "e1") unnoticed. 's high-level point to read into a string is correct; 's digit-only loop is a useful starting idea but misses signs, whitespace, empty input, overflow and cases like exponent notation. and are right to expect a fuller explanation.

A robust pattern in C is: read the whole line (for example with fgets), then use strtol (or strtoll) to convert while inspecting the end pointer and errno. strtol sets endptr to the first character it did not convert, so you can reject input when that pointer does not point to only whitespace and the string terminator. Also set errno = 0 before the call and check for ERANGE to catch overflow. See the strtol documentation for details: strtol on cppreference.

A minimal, safe flow:

  • read a line into a buffer;
  • skip leading whitespace and reject purely empty lines;
  • call strtol(..., 10) with errno = 0;
  • if no characters were consumed, reject;
  • skip trailing whitespace after endptr; if anything remains, reject (this will reject "123e1");
  • check errno == ERANGE and that the result fits your target type (e.g., INT_MIN/INT_MAX).

Example code implementing these checks (trim/trailing-newline handling included):

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

/* returns 1 on success, 0 on failure */
int parse_int_line(int *out) {
    char buf[256];
    if (!fgets(buf, sizeof buf, stdin)) return 0;
    char *p = buf;
    while (isspace((unsigned char)*p)) p++;
    if (*p == '\0' || *p == '\n') return 0;

    errno = 0;
    char *end;
    long v = strtol(p, &end, 10);
    if (p == end) return 0;

    while (isspace((unsigned char)*end)) end++;
    if (*end != '\0' && *end != '\n') return 0;

    if (errno == ERANGE || v < INT_MIN || v > INT_MAX) return 0;

    *out = (int)v;
    return 1;
}

If float syntax (like "123e1") should be accepted, use strtod instead and apply the same end-pointer checks. For very large integers use strtoll.

Recommended Answers

All 6 Replies

Read the input into a string, not a numerical variable. Then validate the string. Once validated convert the string into a numerical variable.

Lerner, he may be asking how to validate it.
If so you somewhat like this

BOOL IsNumber(char szString[])
{
   for(i = 0; szString[i] != 0; i++)
   {
      if(szString[i] >= '0' && szString[i] <= '9')
      {
         // This carachter is number.
      }
      else
         return FALSE;
         // This one ain't, your outta here.
   }
   return TRUE;
}
Member Avatar for Member #46692

Lerner, he may be asking how to validate it.
If so you somewhat like this

BOOL IsNumber(char szString[])
{
   for(i = 0; szString[i] != 0; i++)
   {
      if(szString[i] >= '0' && szString[i] <= '9')
      {
         // This carachter is number.
      }
      else
         return FALSE;
         // This one ain't, your outta here.
   }
   return TRUE;
}

I don't think that would work.

Why not?

Member Avatar for Member #46692

try it.

I don't think that would work.

Why not?

Agree. If you're going to complain about something, the least you can do is give some kind of explanation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.