【问题标题】:Check if all values entered into char array are numerical检查输入到 char 数组中的所有值是否都是数字
【发布时间】:2020-11-25 19:49:10
【问题描述】:

我有一个 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: ");
    }
}       

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

附:我知道有一种方法可以确保只输入数值,考虑到 字符,与数字不同,包含在单引号中。(不知道如何执行此操作)

提前致谢!

【问题讨论】:

  • 你在哪里将i设置为0?
  • 我建议用strtol()转换字符串,这样你就可以测试转换停止的字符,或者strtoll()
  • 我不确定我是否明白了你的问题。我一开始就将 i 设置为 0。 @斯塔克
  • 那么第二个号码上的i 是什么?

标签: arrays c char


【解决方案1】:

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

简单的方法是使用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;
}

【讨论】:

  • 次要:“如果不是,fgets 必须截断行(即)// 行太长而无法放入缓冲区”或读取了一些文本(不是完整的缓冲区)和 @ 987654325@ 导致文件结束。
【解决方案2】:

在 C 中处理来自 stdin 的输入可能会很痛苦。我试图解释在 cmets 中需要做什么,同时以您希望使用它们的方式维护您的变量。但我确实需要添加int ch 来捕获来自stdin 的输入。我捕获输入的方式很远!来自理想,但它说明了这个想法并做了你需要做的事情。但是,为了改进你的答案,我建议将它移到它自己的功能中。此外,它会忽略大于 10 个字符的数字输入,因此,例如,如果您输入 012345678901234567,它只会忽略第 10 位之后的输入,但仍会根据您的变量和标志通过测试。 cmets 应该是不言自明的。我没有对此进行测试,只是确保它已编译,一次用于数字,一次用于数字和文本,但想法就在那里,您应该能够对其进行扩展以满足您的要求。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h> /* for fflush */

int main()
{
    int f = 1; /* set f on */
    int i = 0;
    int flag = 0; /* set flag OFF */
    char num[11];
    int ch; /* adding ch to read characters from stdin */
    
    printf("Enter a number: "); /* flush stdout if no newline */
    fflush(stdout);

    while(f == 1) {

        /* you need to read stdin to the newline */
        /* but not exceed the bounds of num */
        ch = fgetc(stdin);
        while(ch != '\n' && ch != EOF) {
            if(i < 10) /* reusing your i variable that you set to 0, don't exceed 10 to save space for '\0' */
                num[i] = ch;
            i++;
            ch = fgetc(stdin); /* get another character */
        }
        /* now add '\0' to terminate your string */
        /* but not beyond num[10] */
        if(i > 10) {
            num[10] = '\0';
        } else {
            num[i] = '\0';
        }
        
        /* now that we are done reading stdin reset i to 0 to restore how you had it */
        i = 0;
        
        /* lets test num working with your variables */
        while(num[i] != '\0' && flag == 0) {
            /* test for digit at num[i] */
            if(!isdigit(num[i]))
                flag = 1; /* not a digit so set your flag variable on */
            i++;
        }
        
        /* process your flag variable */
        if(flag == 0) { /* flag is off so everything is ok */
            f = 0; /* turn f off to exit loop */
        } else { /* flag is on, so get another number */
            printf("Enter numerical char: "); /* flush stdout if no newline */
            fflush(stdout);
            flag = 0; /* turn your flag variable back off */
            i = 0; /* reset i to 0 to check the next input */
        }
        
    }
    
    /* let's see what we got in num */
    printf("%s\n", num);
    
    return 0;
}

【讨论】:

    猜你喜欢
    • 2021-01-07
    • 1970-01-01
    • 2020-09-19
    • 2016-06-08
    • 2015-04-12
    • 2022-01-14
    • 1970-01-01
    • 2013-07-25
    • 2015-01-08
    相关资源
    最近更新 更多