【问题标题】:Wanted to check if the value entered is a number or else. "isdigit() is not working here as expected想要检查输入的值是数字还是其他。 “isdigit() 没有按预期工作
【发布时间】:2018-06-10 21:12:37
【问题描述】:

我在 C 语言中遇到了一个问题。我发布了问题和我在下面编写的代码。在这里,我必须在一个数组中输入 10 个数字,然后我需要检查一个数字出现了多少次。但是为了验证我输入了一个数字而不是其他任何东西,我使用了“isdigit()”函数。但这没有用。谁能帮我解决一下。

/* (a) 十个数字从键盘输入到一个数组中。要搜索的号码是通过输入 用户的键盘。编写程序查找要搜索的数字是否存在于数组中,如果存在则显示 它出现在数组中的次数。 */

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

main()
{
    int num[10];
    int i, j, cnt=0;
    char rept;

    printf("Enter 10 numbers: \n\n");

    for(i=0; i<=9; i++)
    {
        printf("Number %d =  ", i+1);
        scanf("%d", &num[i]);

            fflush(stdin);

        if ( !isdigit(num[i]) )
            {
                printf("OK\n");
            }
        else
            {
                printf("Invalid number. Enter again.\n");
                i=i-1;
            }
    }


    do
    {

    printf("\nEnter the number to be searched in array:  ");
    scanf(" %d", &j);

    for (i=0 ; i<=24; i++)
    {
        if(num[i]==j)
            cnt++;

    }

        if(cnt>0)       
         printf("\nNumber %d is present at %d places", j, cnt);
         else
            printf("\nNumber not present.");

            printf("\n\nDo you want to search another number. Press Y to repeat. Any other key to exit");
            fflush(stdin);
             scanf("%c", &rept);


    }while (rept=='y'||rept=='Y');

    getch();

}

【问题讨论】:

  • 谁或什么文字建议使用fflush(stdin);
  • 您是否阅读了scanf() 的文档?尤其是讨论其返回值的部分?
  • 另外请记住,main() 在 20 年前就已经过时了,并且在 2011 年被认定为非法。请使​​用 int main(void)
  • @Coolbuddy comment 没有回答 question。但你的电话。

标签: c


【解决方案1】:

不,你不能那样做。 isdigit() 应该与字符一起使用,并且您传递了一个 multigit 整数变量。

你能做的就是这样

if( scanf("%d",&a[i])== 1){
  // you can be sure number is entered
}

fflush(stdin) 是未定义的行为。

所以如果你这样做,scanf 的使用会更加突出

int clearstdin(){
  int c;
  while ((c = getchar()) != '\n' && c != EOF);
  return (c == EOF);
}

main()

int earlyend = 0;
for(size_t i=0; i<SIZE; i++){
...
... 
    int ret = scanf("%d",&a[i]); 
    while( ret == 0){
         if( clearstdin() ){ /* EOF found */earlyend = 1; break; }
         fprintf(stderr,"%s\n","Entered something wrong");
         ret = scanf("%d",&a[i]);
    }
    if( earlyend ){ /*EOF found*/ }
    if( ret == EOF) { /* Error occured */}
...
}

【讨论】:

    【解决方案2】:

    %d 转换说明符将导致scanf 跳过任何前导空格,然后读取一系列十进制数字,在第一个非数字字符处停止。如果输入中没有数字字符(例如,您输入类似”abc” 的内容),则不会从输入流中读取任何内容,a[i] 不会更新,scanf 将返回 0 以指示 匹配失败

    所以,你可以做一个类似的测试

    if ( scanf( “%d”, &a[i] ) == 1 )
    {
      // user entered valid input
    }
    

    但是……

    这并不能完全保护您免受错误输入的影响。假设您输入类似 ”123abc” - scanf 的内容将读取、转换和分配 123 并返回一个表示成功的 1,而将 ”abc” 留在输入流中可能会破坏下一次读取。

    理想情况下,你想彻底拒绝整个事情。就个人而言,我这样做如下:

    char inbuf[SOME_SIZE];  // buffer to store input
    
    if ( fgets( inbuf, sizeof inbuf, stdin ) ) // read input as text
    {
      char *chk;                                  // use strtol to convert text to integer
      int temp = (int) strtol( inbuf, &chk, 10 ); // first non-digit character written to chk
      if ( isspace( *chk ) || *chk == 0 )         // if chk is whitespace or 0, input is valid
      {
        a[i] = temp;
      } 
      else
      {
        // bad input
      }
    }
    

    这仍然不是 100% 的解决方案 - 它不能确保用户输入的字符数不会超过缓冲区的容量,但这是朝着正确方向迈出的一步。

    坦率地说,C 中的输入验证是一件很头疼的事。

    【讨论】:

      猜你喜欢
      • 2016-09-07
      • 2013-12-15
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2016-03-16
      相关资源
      最近更新 更多