【问题标题】:Using scanf to read an integer with nothing else but a newline character使用 scanf 读取一个只有换行符的整数
【发布时间】:2020-12-16 17:39:31
【问题描述】:

有没有办法使用 scanf(不使用任何其他 I/O 函数)来检查用户输入是否仅存在于单个整数之后没有任何内容?

例如:

int g;
while(scanf("%d", &g)!=1){
    printf("\nincorrect input, try again");
}

这适用于像“/”或“-”这样的输入,但是当您输入“54.32”时,它将一直读取到“.”,scanf 的读取计数将为 1,54 将存储在 g 中。有没有办法检查输入是否仅由一个整数组成,后跟一个换行符?

我想知道是否存在不使用 fgets 或任何其他 IO 功能的解决方案?

【问题讨论】:

  • scanf 用于读取格式化输入。对无格式输入无用。
  • "%d%c" 然后如果返回 2 并且字符不是 '\n' - 存在无关字符。 (但您确实应该使用 fgets() 进行所有用户输入,如果需要,使用 sscanf() 进行转换)

标签: c scanf


【解决方案1】:

只检查一个整数,后跟一个换行符

使用"%n" 记录扫描的字符数,如果它已经到了那么远。

int n = 0;
scanf("%d*1[\n]%n", &g, &n);
if (n > 0) puts("input consists solely of a single integer followed by a newline");

如果结果不是,则需要额外的代码来处理错误的输入。

我建议使用fgets() 来解决更大的问题。

【讨论】:

  • 我看到测试被颠倒了,只是花了一点时间才发现使用了匹配失败来阻止到达"%n"。我仍然需要"%d%*1[\n]%n" 才能获得所需的行为。
【解决方案2】:

编辑因为我误解了这个问题:这个怎么样?

#include <stdio.h>

int main() {

    int n;
    char c;

    scanf("%d", &n);

    scanf(" %c", &c) ? printf("incorrect input, try again\n") : printf("%d\n", n);

    return 0;
}

【讨论】:

  • OP 确实要求“后跟一个换行符”。此答案未检测到换行符是否成功跟随int。它确实与标题相符。
  • @chux-ReinstateMonica 当用户输入54.32 时,OP 要求读取54,这是一个浮点数,或者一个整数,后跟一个点,然后是另一个整数。在任何情况下,该程序甚至适用于仅后跟换行符的 intgeers。
  • @chux-ReinstateMonica 重新阅读问题,我实际上可能弄错了。对不起。
  • OP 发布的目标有点矛盾,并且没有解决当输入不符合预期时应该保持未读的内容。 IAC,OP 喜欢这个答案
  • @chux-ReinstateMonica 很好,即使他喜欢我编辑的答案以匹配他在问题中提出的问题。谢谢你让我注意到我的错误
【解决方案3】:

您可以使用抑制赋值的格式运算符提取整数之后的所有内容(任何内容),并使用 number-of-characters-read 格式说明符来查看是否匹配任何内容,而无需存放在任何地方。

查看您的documentation

例如,

int g, gchars, xchars;
scanf("%d%n%*s%n", &g, &gchars, &xchars);
if (xchars > gchars)
    printf("%d extra characters discarded after integer %d\n", xchars-gchars, g);

【讨论】:

  • %*s 使用int 之后可能存在 的任何换行符。它不能用于区分换行符是否跟随int 或其他内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多