【问题标题】:Read 2 integers from user input in c从 c 中的用户输入中读取 2 个整数
【发布时间】:2014-02-14 21:23:18
【问题描述】:

所以我的程序必须从用户输入中读取 2 个整数并打印出来。我使用scanf,程序将在输入错误时退出。但是,当输入为“3+2”或“3-2”时,scanf 会忽略“+”和“-”符号,并将 3 和 2 作为两个整数输入读取。我想要 3+2 和 3-2 作为错误输入,程序将退出。我该如何解决?

int num1, num2;
if (scanf("%d%d", &num1, &num2) != 2) {
        //bad input, exit the program
    }
    else {
        //print the two integers

【问题讨论】:

  • 从技术上讲,它读取两个整数...
  • 当你给这两个值时,将它们分开。例如 3 2
  • "-" 符号不会被忽略。 (也是“+”)
  • 你想让它做什么?当我运行它并输入 3-2 它打印 3 然后 -2 这是两个整数。
  • 那么要求是两个值之间有一个空格?有一个模因“对你接受的东西要慷慨;对你生产的东西要严格”(给予或接受)它说你应该尽量容忍次优的输入,但要小心产生正确形成的输出。你可能想考虑一下。

标签: c input integer scanf


【解决方案1】:

您必须自己验证字符串。考虑以下几点:

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

#define MAX_STR_LEN (50)

int main(void)
{
    char str[MAX_STR_LEN] = {0};
    int num1, num2;

    printf("Enter two numbers: ");
    fgets(str, MAX_STR_LEN, stdin);

    for(int i = 0; i < MAX_STR_LEN; i++)
    {
        if(!isdigit(str[i]) && (!isspace(str[i])) && (str[i] != '\0'))
        {
            if((i != 0) && (str[i - 1] != ' ') && ((str[i] != '+') || (str[i] != '-')))
            {
                printf("'%c' is bogus! I'm self destructing!", str[i]);
                return -1;
            }
        }

        if((str[i] == '\n') || (str[i] == '\0'))
            break;
    }

    sscanf(str, "%d%d", &num1, &num2);
    printf("You entered %d and %d. Good job.  Pat yourself on the back.", num1, num2);

    return 0;
}

逻辑如下:

  1. 将用户输入作为通用字符串读取。
  2. 在字符串中搜索违规字符或字符序列。
  3. 如果没有,则相应地解析字符串。
  4. 坐下来幸灾乐祸。

【讨论】:

  • 第 4 点得到了我的支持。第 1 点很关键 - scanf 只是一个糟糕的函数,应该将其放入口袋里有石头的深井中。您可能要考虑用户可以在两个值之间放置一个 CRLF。我认为这是合法的,但你的代码(还)没有抓住它。
  • 任何时候scanf() 需要两个或多个数值,您可以在值之间有任意数量的换行符(从 0 向上)。这是fgets() 加上sscanf() 与普通scanf() 相比的另一个优势。与字符串 (%s) 类似。 IIRC,只有两个转换说明符 %[...]%c%n 不要跳过前导空格;其他所有操作,空格包括换行符。
【解决方案2】:

由于要求似乎在输入行中的两个数字之间至少有一个空格字符,因此代码需要类似于:

char s[2];
if (scanf("%d%1[ \t]%d", &num1, s, &num) != 3)
    ...format error...

这 (%1[ \t]) 在第一个数字之后立即查找空白或制表符。第二个数字之前可能有额外的空格。除非您愿意,否则您不必对 s 中的值做任何事情。

已修复以响应来自chux 的准确comment

【讨论】:

  • %[ \t] 有困难,因为它扫描了一个长度不定(由空格和制表符组成)的 string 将结果放入char c
  • 确实如此,但很容易被%1[ \t] 修复,它将一个字符读入一个以空字符结尾的字符串...
【解决方案3】:

使用"%n" 扫描以检测分隔空白。

int num1, num2;
int n1, n2;
if (scanf("%d%n %n%d", &num1, &n1, &n2, &num2) != 2) {
  ; // bad input, exit the program
}
if (n1 == n2) {
  ; // no space between 1st and 2nd number, exit the program
}

另一种方法,类似于@Jonathan Leffler,只接受至少 1 个空格

if (scanf("%d%*[ ]%d", &num1, &num2) != 2) {
  ; // bad input, exit the program
}

同意许多其他人的说法:使用fgets()/sscanf() 要好得多。

【讨论】:

    猜你喜欢
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    相关资源
    最近更新 更多