首页 > 解决方案 > 检查输入到 char 数组中的所有值是否都是数字

问题描述

我有一个 char 数组,其中应该只有数字(10 位数字)。如果用户输入字母或特殊字符(即使在这些数字中),程序应该再次提示用户输入数字。

我尝试了很多方法,但仍然找不到方法。到目前为止,这就是我能做的:

int f = 1;
int i = 0;
int flag =1;
char num[11];
printf("Enter a number: ");

while (f == 1) {
    scanf("%10s", num);

    while (flag == 1 && isdigit(num[i])) {
        i++;
        if (i == 10) {
            f = 0;
            flag =0;
        }
    }

    if (!isdigit(num[i])) {
        printf("Enter numerical char: ");
    }
}       

在我输入不正确的值后,它显示一个空行。如果我在该空行中输入任何值,那么它只会显示“输入数字字符:”并提示再次输入数字。

PS我知道有一种方法可以确保只输入数值,考虑到字符与数字不同,它包含在单引号中。(不知道如何做到这一点)

提前致谢!

标签: arrayscchar

解决方案


有几种方法可以做到这一点。

简单的方法是用来fgets获取字符串。

然后,我们可以使用strtol解码数字[并检查结束字符的有效性]。

要完全手动完成,我们可以isdigit循环使用,一次建立一个数字。

这是一些带注释并显示两种方式的示例代码:

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

// getstr -- get a string with prompt
// RETURNS: length or (<0 -> error)
int
getstr(char *buf,int buflen,const char *prompt)
{
    char *cp;
    int ret = 0;

    // NOTE: usage of the error codes in errno.h is arbitrary

    while (ret <= 0) {
        // ensure buffer has enough space
        if (buflen < 2) {
            ret = -ENOMEM;
            break;
        }

        // output prompt
        printf("%s: ",prompt);
        fflush(stdout);

        // get a line
        cp = fgets(buf,buflen,stdin);

        // EOF
        if (cp == NULL) {
            ret = -ENODATA;
            break;
        }

        // get buffer length
        ret = strlen(buf);

        // empty string
        if (ret <= 0)
            continue;

        // point to last char
        cp = &buf[ret - 1];

        // ensure we got a newline -- if not, fgets had to chop the line (i.e.)
        // the line is too long to fit in the buffer
        if (*cp != '\n') {
            ret = -ENOSPC;
            break;
        }

        // strip the newline -- we are done
        *cp = 0;
        --ret;
    }

    return ret;
}

// getnum_strtol -- get number using strtol
long
getnum_strtol(const char *prompt)
{
    int len;
    int readflg = 1;
    char *cp;
    char buf[100];
    long num = 0;

    while (readflg) {
        len = getstr(buf,sizeof(buf),prompt);

        if (len < 0)
            exit(1);

        num = strtol(buf,&cp,10);

        // ensure we got a least one digit
        if (cp <= buf)
            continue;

        switch (*cp) {
        case ' ':
        case '\t':
        case 0:
            readflg = 0;
            break;
        default:
            printf("getnum_strtol: not a valid number -- buffer '%s', invalid '%s'\n",
                buf,cp);
            break;
        }
    }

    return num;
}

// getnum_manual -- get number _not_ using strtol
long
getnum_manual(const char *prompt)
{
    int len;
    int readflg = 1;
    int sign = 0;
    int valid;
    int chr;
    char *cp;
    char buf[100];
    long num = 0;

    while (readflg) {
        len = getstr(buf,sizeof(buf),prompt);

        // fatal error
        if (len < 0)
            exit(1);

        // point to buffer start
        cp = buf;

        // find first non-whitespace character
        valid = 0;
        while (1) {
            chr = *cp;

            // end of string
            if (chr == 0)
                break;

            // found character
            valid = ((chr != ' ') && (chr != '\t'));
            if (valid)
                break;

            ++cp;
        }
        if (! valid)
            continue;

        // reset the accumlated number and the sign
        num = 0;
        sign = 0;
        valid = 0;

        // loop through all characters in buffer
        while (1) {
            chr = *cp++;

            // get the sign of the number (and skip an explicit sign)
            if (sign == 0) {
                switch (chr) {
                case '+':
                    sign = 1;
                    chr = *cp++;
                    break;
                case '-':
                    sign = -1;
                    chr = *cp++;
                    break;
                default:
                    sign = 1;
                    break;
                }
            }

            // stop decoding number on whitespace
            switch (chr) {
            case ' ':
            case '\t':
                chr = 0;
                break;
            }

            // check for clean end of number
            if (chr == 0) {
                if (valid) {
                    readflg = 0;
                    break;
                }
            }

            // not a valid digit
            if (! isdigit((unsigned char) chr)) {
                cp -= 1;
                printf("getnum_manual: not a valid number -- buffer '%s', invalid '%s'\n",
                    buf,cp);
                break;
            }

            // add digit to number
            num *= 10;
            chr -= '0';
            num += chr;

            // we got at least one valid digit
            valid = 1;
        }
    }

    // apply sign
    num *= sign;

    return num;
}

int
main(int argc,char **argv)
{
    char *cp;
    int opt_s = 0;
    long num;

    // skip over program name
    --argc;
    ++argv;

    // get options
    for (;  argc > 0;  --argc, ++argv) {
        cp = *argv;
        if (*cp != '-')
            break;

        cp += 2;
        switch (cp[-1]) {
        case 's':  // use strtol
            opt_s = ! opt_s;
            break;
        }
    }

    while (1) {
        if (opt_s)
            num = getnum_strtol("Enter number [strtol]");
        else
            num = getnum_manual("Enter number [manual]");
        printf("The number entered is: %ld\n",num);
        if (num == 999)
            break;
    }

    return 0;
}

推荐阅读