【问题标题】:scanf read variable number of charactersscanf 读取可变字符数
【发布时间】:2017-11-08 20:35:33
【问题描述】:

我想知道如何让scanf 按回车键跳过读取字符...我的代码如下:

#include <stdio.h>

int main(void)

{
    int a, status;
    char b;
    printf("Please enter a positive number immediately"
           "followed by at  most one lower-case letter:\n\n");
    status = scanf("%i%c", &a, &b);
    if (status == 1 && getchar() == '\n') {
        printf("\nThank you!\n");
    }
    return 0;
}

当我只输入一个数字而不输入其他内容时,我需要再次按 Enter 以触发scanf 中的%c&amp;b。如何避免这种情况并让程序只接受 1 个号码以跳转到 printf
我试过了:

if (status == 1 && getchar() == '\n')

但这行不通。

【问题讨论】:

  • 我建议使用fgets读取整行,然后使用sscanf转换行首的数字,如果有的话。
  • 如果scanf("%i%c"...) 成功,它将返回2,而不是1fgets 在这里更有意义。
  • 好吧,我才刚开始编程,所以我对 fgets 不熟悉。在这种情况下我将如何使用它?你能把这条线发给我吗?
  • 如果您在scanf() 之后添加一行:printf("%d [%c] = %d\n", a, b, status);,对给出的内容进行调试打印,并且如果您输入31 作为数字,那么您会看到@987654337 @ 在一行,] = 2 在下一行,因为 %c 会将换行符读取为字符,并且因为 scanf() 整体将返回 2,因为它成功转换了两个值。如果您使用"%i%[a-z]" 作为格式字符串,那么您将在status 中返回1,在a 中返回31,在b 中返回垃圾。

标签: c


【解决方案1】:

如 cmets 中所述,您最好的做法是使用 fgets 来读取字符串,然后对其进行解析和验证。 This Thread 将为您提供足够的资源,让您了解fgets 的使用。

这是您可以采取的一种方法。请注意,此代码不会尝试验证用户可以提供的每个可能的输入,而是为您提供一个合理的方向,如果输入被假定为正确,您可以解决您的问题。我将把验证的任务留给你。下面的代码应该提供足够的工具来完成您的其余任务。查看使用for 循环来单步执行buffer 并确保输入正确。使用isalpha()isdigit() 测试每个字符。您还可以实现自己的函数来测试每个角色的完成情况
this answer

#include <stdio.h>
#include <stdlib.h> //for atoi() 
#include <string.h> //for strlen() 
#include <ctype.h> //for isalpha()
#define MAX_INPUTLENGTH 500
int main(void)
{
    //Always a good idea to initialize variables to avoid Undefined Behaviour!
    char buffer[MAX_INPUTLENGTH] = { '\0' };
    int a = 0, status = 1, length = 0;
    char b = '\0';

    printf("Please enter a positive number immediately"
        "followed by at  most one lower-case letter:\n\n");

    //this gets you a string you can work with
    fgets(buffer, sizeof(buffer), stdin);
    length = strlen(buffer);
    buffer[length - 1] = '\0';//remove the trailing '\n'
    length--;

    //now see if last character is a letter
    if (isalpha(buffer[length - 1])) {
        b = buffer[length - 1];//then assign and..
        buffer[length - 1] = '\0';//trim the letter
    }

    //this function converts the remaining string to an int
    a = atoi(buffer);

    //Use the debugger and observe how these functions work in order
    //to validate the input. for now, status is always 1!
    if (status == 1) {
        printf("\nThank you!\n");
    }
    return 0;
}

正如@Jonathan 在下面的 cmets 中所指出的,要便携地获取数组的计数,应该使用 sizeof(buffer) / sizeof(buffer[0])。由于您使用的是char[],因此sizeof(buffer[0]) 的计算结果为1,因此在调用fgets 时可以省略。

【讨论】:

  • 请注意,_countof() 是 MS 特有的功能。在这里并不完全合适。使用sizeof() 既便携又正确。在这种情况下,_countof() 返回的值与 sizeof() 的返回值相同,因为 sizeof(buffer[0]) == 1
  • 还要注意你的逻辑不会被用户输入31 ants打乱;它会很乐意将s 视为“一个小写字母”(因为缓冲区只有10 个字符长,如果您输入31 elephants,您将留下ts 以及换行符未读;如果您输入2000000000a,您将留下a 未读)。您还需要&lt;string.h&gt;(对于strlen())和&lt;stdlib.h&gt;(对于atoi())。
  • @JonathanLeffler,感谢您的 cmets。我相应地对我的答案进行了编辑。非常感谢此反馈,因为我对 SO 还比较陌生,并且仍在学习如何给出最佳答案。像你这样的人会帮助我更快到达那里!
猜你喜欢
  • 2013-07-04
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多