简体   繁体   English

检查用户输入的值是否为数字的基本/手动方法

[英]A basic/ manual way to check that a value entered by the user is numeric

I've searched in and out of these forums but am still having trouble. 我已经搜索了这些论坛,但仍然遇到麻烦。 My understanding of C is still very basic. 我对C的理解仍然很基础。 I'm creating a small program that takes 3 numerical values entered by the user and then calculates the highest. 我正在创建一个小程序,该程序接受用户输入的3个数值,然后计算出最大值。 I nailed that. 我钉了

I now want to ensure that the user enters only integer values. 现在,我要确保用户仅输入整数值。 I managed to get the prog to keep prompting the user to re-enter the value until it is within the specified numerical range (for example, any number between 1 and 1000 inclusive, piece of cake) but that's not good enough. 我设法使prog不断提示用户重新输入该值,直到该值在指定的数字范围内(例如,介于1到1000之间的任何数字,包括小菜一碟),但这还不够好。 I used 3 while loops to test each value, but this only works as long as the input is of type integer. 我使用了3个while循环来测试每个值,但这仅在输入为整数类型时才有效。

The trick is I cant use built in functions. 诀窍是我不能使用内置函数。 It needs to be manual (sorry, poor choice of words) I tried to use char variables and x = getchar(); 它必须是手动的(抱歉,单词选择不佳),我尝试使用char变量,并且x = getchar();。 to get the ASCII value and test it in a condition but I can't get it working in a loop. 获取ASCII值并在某种条件下对其进行测试,但我无法使其在循环中工作。 (while/ do-while) (一会/一会儿)

I also tried using a "for loop" and array variables but once again am struggling to get it to keep prompting the user. 我也尝试使用“ for循环”和数组变量,但再次努力使它不断提示用户。

I've also tried to test the value returned by scanf to see if its integer but my knowledge level of correct C syntax is level: noob. 我还尝试测试scanf返回的值,以查看其整数是否正确,但我了解正确的C语法的知识水平是:noob。 Either my loops don't loop or they loop infinitely. 我的循环不循环或无限循环。

Here is some sample code: 这是一些示例代码:

int x, y, z =0;

printf("Enter the first number:\n");
scanf("d", &x);
while (condition) /* Here is where I need to determine that the entered val is false */
{
    printf("Wrong input. Re-enter a valid value.\n");
    x =0;
    scanf("%d", &x); /*user re-prompted */
}

I'm getting the idea that I'll have to use ASCII and a loop, but I just can't get to it. 我的想法是必须使用ASCII和循环,但是我无法理解。 Also, the values entered get sent to a function for comparing and are then returned. 同样,输入的值将发送到函数进行比较,然后返回。

Could someone give me some advice and a few tips please? 有人可以给我一些建议和一些提示吗?

Much thanks 非常感谢

You would have to use something like fgets , and strtol : 您将必须使用fgetsstrtol类的东西:

long someValue;

char *bufEnd = NULL;
char buf[128]; // max line size

do {
    printf("enter a value: ");
    fgets(buf, 128, stdin);
    someValue = strtol(buf, &bufEnd, 10); // base 10
} while (bufEnd == buf || *bufEnd != '\n');

printf("got value: %li", someValue);

What we are doing here is we are tapping into strtol 's capability to tell us where it stopped parsing, by passing in bufEnd . 我们在这里所做的是通过传入bufEnd来利用strtol的功能来告诉我们停止解析的bufEnd

Then, we are making sure that bufEnd doesn't point to the beginning of buf (in which case, it didn't start with a number), and also checking to make sure that bufEnd points to \\n , or the end of the line (making sure that the user didn't enter something like 123abc , which strtol would interpret as 123 ). 然后,我们要确保bufEnd不指向buf的开头(在这种情况下,它不是以数字开头),并且还要检查以确保bufEnd指向\\n或结尾处行(确保用户未输入123abc东西, strtol将其解释为123 )。 You may wish to trim buf of whitespace characters first, however. 但是,您可能希望先修剪空白字符的buf

You're absolutely on the right track with "scanf()". 使用“ scanf()”绝对是正确的选择。 Just check the return value. 只需检查返回值即可。 If you don't get the expected #/values, then you got invalid input: 如果没有获得预期的#/值,则输入无效:

char found = FALSE;
int ival;
double x;

while (!found)
{
    printf("Please enter a valid integer: ");
    if (scanf("%d", &ival) !=1) {
      printf ("Invalid!  Please re-enter!\n");
      continue;
    }
    printf("Please enter a valid floating point number: ");
    if (scanf("%lf", &x) !=1) {
      printf ("Invalid!  Please re-enter!\n");
      continue;
    }
    found = TRUE;
}

Here's my solution. 这是我的解决方案。 It safe against buffer overflow and straightforward . 它可以防止缓冲区溢出和直接攻击。

#include <stdio.h>
#define LEN 10

int main() {
    int a;
    char str[LEN];
    fgets( str, LEN, stdin );
    while ( !sscanf( str, "%d", &a ) )
        fgets( str, 10, stdin );
    printf("Num is : %d\n", a);
    return 0;
}
#include <stdio.h>
#include <limits.h>
#include <ctype.h>

int getInteger(int* err){
    int ch;
    int n;//int32
    int takeNum, sign;
    long long int wk;//long long int as int64

    wk=0LL;
    *err = 0;
    takeNum = 0;//flag
    sign = 1;//minus:-1, other:1
/*  //skip space character
    while(EOF!=(ch=getchar()) && (ch == ' ' || ch == '\t' || ch == '\n'));
    ungetc(ch, stdin);
*/
    while(EOF!=(ch=getchar())){
        if(ch == '-'){
            if(takeNum != 0){//in input number
                *err = 1;
                break;
            }
            if(sign == -1){//already sign
                *err = 2;
                break;
            }
            sign = -1;
            continue;
        }
        if(ch >= '0' && ch <= '9'){//isdigit(ch) in ctype.h
            if(takeNum == 0)
                takeNum = 1;
            wk = wk * 10 + (ch - '0')*sign;
            if(INT_MAX < wk || INT_MIN > wk){//overflow
                *err = 3;
                break;
            }
            continue;
        }
        if(ch != '\n'){//input other [-0-9]
            *err = 4;
        }
        break;
    }
    if(takeNum == 0){//not input number
        *err = 5;
    } else {
        n=wk;
    }
    while(ch != '\n' && EOF!=(ch=getchar()));//skip to newline
    return n;
}

int getValue(const char* redoprompt, int low, int high){
    int num, err=0;

    while(1){
        num = getInteger(&err);
        if(err || low > num || high < num)
            printf("%s", redoprompt);
        else
            break;
    }
    return num;
}

#define max(x,y) ((x)>(y))? (x) : (y)

int main(){
    const char *error_message = "Wrong input. Re-enter a valid value.\n";
    int x, y, z, max;

    x = getValue(error_message, 1, 1000);
    y = getValue(error_message, 1, 1000);
    z = getValue(error_message, 1, 1000);
    max = max(max(x,y), z);
    printf("max:%d\n", max);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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