【问题标题】:Error check user input with integers in C使用 C 中的整数错误检查用户输入
【发布时间】:2020-02-19 03:47:16
【问题描述】:

我正在尝试获取用户以 #1、#2、#3 格式输入的 RGB 代码。我对输入进行错误检查以确保它与 ', ' 格式匹配,并且可以从字符串中提取数字。但是,之后我无法检查输入是否为数字。

例如:如果用户输入:255, 0, 0f 程序仍然运行。

任何帮助将不胜感激!

char input[100];
printf("Enter RGB code \n");
scanf(" %[^\n]s", input);

//function to error check ', ' format

int c1,c2,c3;
//formats the input into three ints. 
sscanf(input, "%d, %d, %d\n", &c1,&c2,&c3);

我只需要检查这些是否实际上是整数

【问题讨论】:

  • " %[^\n]s" 的末尾没有's',除非您输入格式"#1, #2, #3s" -- 删除它:) 转换说明符%[...] .此外,您无法正确使用任何用户输入函数或转换函数,除非您检查返回...使用fgets( input, sizeof input, stdin) 而不是scanf(" %[^\n]s", input);——消除@ 987654329@ 陷阱。 (同时从"%d, %d, %d\n" 中删除'\n'
  • "我错误检查输入以确保它与 ', ' 格式匹配" --> 代码不会这样做,因为它不会检查 scanf() 的返回值。

标签: c


【解决方案1】:

一种至少应该更稳健的方法:

char input[100];
/* use fgets - it's the safer way to read a line.
   scanf("%[^\n]", input); can result in a buffer overflow! */
fgets(input, sizeof(input), stdin);

int c1, c2, c3, end;
/* Check the return value of sscanf to ensure we read exactly three ints.
   We then use %n to check that we read up to the end of the string.
   The \n before the %n skips all whitespace at the end of the string.
*/
if(sscanf(input, "%d,%d,%d\n%n", &c1, &c2, &c3, &end) != 3 || input[end] != '\0') {
    printf("invalid input!\n");
}
...

这是做什么的:使用fgets 读取一行(更安全,没有缓冲区溢出,不像你的scanf),然后使用sscanf 解析它。这里我使用了%n 格式选项,它将到目前为止读取的字符数写入相应的int 参数(这里是end)。然后我们简单地检查我们是否到达了字符串的末尾——如果没有,则必须有尾随垃圾,以便我们可以拒绝输入。此外,我们检查sscanf 的返回值,以确保它读取的恰好是三个数字(%n 不算在内)。

【讨论】:

    【解决方案2】:

    如果您想做任何严格的格式检查,我建议您将PCRE 合并到您的代码中。然后你可以简单地得到一条线(比你现在更强大(scanf 可能不可靠),比如来自this answer 的那条线),然后使用如下正则表达式:

    ^\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*$
    

    检查和提取您想要的字段,每个字段都是一到三位(包括)数字。

    然后您可能想要检查提取的字段是否小于 256,但这应该相对容易。或者,如果您希望所有这些都由正则表达式本身完成,您可以将上述正则表达式中出现的每个 (\d{1,3}) 替换为:

    (0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])
    

    这保证了字段中的0..255 数字,而不是任意的一到三位数字,使用以下可能性:

    0          : 0
    [1-9]\d?   : 1-99
    1\d\d      : 100-199
    2[0-4]\d   : 200-249
    25[0-5]    : 250-255
    

    【讨论】:

      【解决方案3】:

      好的。因此,在将字符数组输入中的输入值放入 c1、c2 和 c3 整数变量之前,您需要检查它们是否实际上是数字。好主意。

      C 中有一个函数可以帮助您做到这一点,除非您想编写自己的函数(我不会在这里冒险,但如果这对您有吸引力,您可能想研究 Ascii 表)。它被称为 isdigit,您可以在此处了解更多信息:https://www.tutorialspoint.com/c_standard_library/c_function_isdigit.htm。它具有以下形式 int isdigit (int c),如果传递的参数是数字,则返回非零值。您可以将输入数组中的字符值传递给它,例如 isdigit(input[x]); 其中 x 是字符数组输入中字符的位置。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2016-05-07
        • 1970-01-01
        • 2020-06-21
        • 2015-01-30
        • 2023-03-18
        • 1970-01-01
        • 2015-06-20
        • 1970-01-01
        • 2010-11-19
        相关资源
        最近更新 更多