【问题标题】:How to prevent non numeric or non character input or symbols and getting desired output in C如何防止非数字或非字符输入或符号并在 C 中获得所需的输出
【发布时间】:2016-01-06 04:37:38
【问题描述】:

这是我从 youtube 教程修改的源代码。该计划的目的是:

它问你的年龄。如果您输入 18 或更多,则询问您的性别而不是打印您可以输入 dude 或 m'lady(取决于您的性别)。如果您的年龄小于 18 岁,则会显示“这里没什么可看的!”

我想确保如果输入不完全符合我的要求(仅数字或仅字符),它会显示“无效输入”。在我的程序中,程序询问年龄的第一部分,当年龄的输入是字母或符号时,它显示无效输入。但是,每当我将字母与 18a 或 18/ 之类的数字结合起来时,它就会显示:

"请输入您的性别。(m/f)" “输入无效。”

另外,如果我输入 18 或更多并转到程序询问性别(m/f)的部分,如果我输入数字或符号,它会显示 Invalid input.. 但是当我像 m1 或 m/ 这样组合时它显示:

“你可以进入这个网站,伙计。”

谁能帮我解决这个问题?

#include <stdio.h>

#include <conio.h>

int main(void)  {

   char gender; 
   int age=0;

   printf("Please enter your age. \n");

   if(scanf(" %d",&age)!=1)  {
      printf("invalid input. \n");
      return 0;
   }

   if(age>=18)  {

      printf("Please enter your gender.(m/f) \n");

      if(scanf(" %s", &gender) !=1)  {
         printf("Invalid input.\n");

         return 0;
      }

      else if(gender== 'm')  {
         printf("You may enter this website dude.\n");
      }

      else if(gender== 'f')  {
         printf("You may enter this website m'lady.\n");
      }

      else  {
         printf("Invalid input. \n");
         return 0;
      }
   }

   else if(age<18)  {
      printf("Nothing to see here! \n\n");
      return 0;
   }

      return 0;
}

【问题讨论】:

  • 嗯,你已经遇到了内存损坏问题。您的“缓冲区”是单个字符。即使只输入了一个字符,它也会在它的末尾写入一个终止的空字节,即到堆栈上的以下位置。
  • 最好的解决方案可能是编写自己的 scanf 函数。

标签: c


【解决方案1】:

如果您想避免这种行为,您应该阅读每个用户选项的整行并完全验证它。

要阅读整行,您可以使用scanf(" %[^\n]",str)(*) 而不是使用%d%s。然后您可以验证用户输入以检查它是否正是您想要的。

额外: 要验证年龄,您可以使用:strtol,如 here 解释的那样,要验证性别,我认为简单的字符串比较就可以了。

(*) 有几个选项可用于读取 C 中的整行(例如 fgets),还有不使用 scanf(" %[^\n]",str) 的理由(可能缓冲区溢出),但我试图向您展示一个解决方案您正在使用的函数,有关此主题的精彩讨论,请查看 this post

【讨论】:

  • 你真的不应该坚持一些scanf() 解决方法。使用fgets() 并确保安全。
【解决方案2】:

您正在处理的问题与使用scanf 读取输入后留在输入缓冲区 (stdin) 中的字符有关。当您读取age 时,转换将读取从stdin 到组成和int 的字节数。 int 后面的任何其他字符都保留在输入缓冲区中。 (例如,18ascanf 读取 18a 在以下之后留在输入缓冲区中:)。

int c, age;

if (scanf (" %d", &age) != 1) {
    printf ("invalid age input - conversion failed.\n");
    return 1;
}

注意:您还可以使用strtol 执行相同的附加字符检查以进行转换并在调用后检查endptr

您的输入缓冲区中留下的'a' 然后被您的gender 测试作为输入。 (因为它已经在输入缓冲区中,所以scanf会根据gender的提示自动读取它)要检查是否所有输入都已被消耗,您可以简单地检查剩余的字符是否在输入缓冲区是'\n'(用户按Enter的结果)。如果输入缓冲区中的下一个字符不是'\n',则在age 之后输入了其他字符。

if ((c = getchar()) != '\n') {
    printf ("invalid input - additional characters.\n");
    return 1;
}

您可以在检查剩余字符后施加年龄限制:

if (age < 18)  {
    printf ("Nothing to see here!\n\n");
    return 1;
}

age 测试的一个简短示例可能是:

#include <stdio.h>

int main (void) {

    int c, age;

    if (scanf (" %d", &age) != 1) {
        printf ("invalid age input - conversion failed.\n");
        return 1;
    }
    if ((c = getchar()) != '\n') {
        printf ("invalid input - additional characters.\n");
        return 1;
    }

    if (age < 18)  {
        printf ("Nothing to see here!\n\n");
        return 1;
    }

    printf ("\n age: %d\n\n", age);

    return 0;
}

示例

$ ./bin/age
18

 age: 18

$ ./bin/age
17
Nothing to see here!

$ ./bin/age
18a
invalid input - additional characters.

$ ./bin/age
aa
invalid age input - conversion failed.

查看一下,如果您有任何问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2013-11-26
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多