两次使用scanf()函数:在一种情况下有效,但在另一种情况下无效 [英] Using scanf() function two times: works in one case but not in other case

查看:181
本文介绍了两次使用scanf()函数:在一种情况下有效,但在另一种情况下无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在学习C编程的基础知识,并且正在练习 scanf()函数。这个非常非常简单的程序接受一个数字和一个字母,并使用 printf()函数显示数字和字母。

I'm the learning the very basics of C programming right now, and I'm practicing the scanf() function. This very, very simple program takes in a number and a letter and uses the printf() function to display the number and letter.

如果我要求用户首先输入数字,该程序将起作用,即,要求输入数字,要求输入字母并打印输入。如果我先要求字母,程序会要求输入字母,但随后不要求输入数字。

If I ask the user to enter the number first, the program works, i.e., asks for a number, asks for a letter, and prints the input. If I ask for the letter first, the program asks for a letter but then doesn't ask for a number.

我尝试了多种方式并对它重新排序,但是

I've tried multiple ways and reordered it, but it doesn't seem to work.

这可行:

#include<stdio.h>
 void main(){
    int number;
    char letter;

    printf("Enter letter...");
    scanf("%c", &letter);

    printf("Enter number....");
    scanf("%d", &number);

    printf("Number entered: %d and letter entered: %c.\n", number, letter);
 }

但是,此组合无效:

#include<stdio.h>
void main(){
    int number;
    char letter;

    printf("Enter number....");
    scanf("%d", &number);

    printf("Enter letter...");
    scanf("%c", &letter);

    printf("Number entered: %d and letter entered: %c.\n", number, letter);
 }

我在第一个程序中得到的输出是:

The output I get for the first program is:

Enter letter...a
Enter number....9
Number entered: 9 and letter entered: a.

哪个是正确的

但是第二个大小写不起作用,我不明白为什么它不起作用-跳过输入字母部分

But the second case doesn't work, and I don't get why it wouldn't work -- skips the "enter letter" part

输出为

Enter number....9
Enter letter...Number entered: 9 and letter entered: 
.

上下文:在上面的示例中,我为字母输入 a,为数字输入 9。 / p>

Context: I entered "a" for letter and "9" for number in the above example.

推荐答案

事实证明,%d 与<$之间有令人惊讶的区别c $ c>%c 。除了%d 可能扫描多个数字而%c 只能扫描一个数字这一事实之外,令人惊讶的区别是 %d 会跳过所有前导空格,而%c 不会

It turns out there's a surprising difference between %d and %c. Besides the fact that %d scans potentially multiple digits while %c scans exactly one character, the surprising difference is that %d skips any leading whitespace, while %c does not.

然后,当您使用 scanf 读取用户输入时,还有一个容易忽视的问题,那就是所有这些都会发生什么换行符- \n 字符-用户按下ENTER键输入内容时会插入吗?

And then there's another easily-overlooked issue when you're using scanf to read user inputs, which is, what happens to all those newlines -- the \n characters -- that get inserted when the user hits the ENTER key to input something?

这就是发生了什么。您的第一个程序

So here's what happened. Your first program had

printf("Enter letter...");
scanf("%c", &letter);

printf("Enter number....");
scanf("%d", &number);

用户键入了一个字母,然后按ENTER,一个数字和ENTER。第一个 scanf 调用读取了这封信,没有其他内容。 \n 保留在输入流中。然后第二个 scanf 调用带有%d 的调用,跳过了 \n (因为 \n 是空格),然后按照您想要的方式读取数字。

The user typed a letter, and ENTER, and a number, and ENTER. The first scanf call read the letter and nothing else. The \n stayed in the input stream. And then the second scanf call, with %d, skipped the \n (because \n is whitespace) and read the number, just like you wanted.

但是在您的第二个程序中,您以其他顺序输入了内容,例如:

But in your second program you had the inputs in the other order, like this:

printf("Enter number....");
scanf("%d", &number);

printf("Enter letter...");
scanf("%c", &letter);

现在,用户键入一个数字并按ENTER键,第一个 scanf 调用读取数字并将 \n 留在输入流中。但是随后在第二个 scanf 调用中,%c 不会跳过空格,因此它读取的字母是 \n 字符。

Now, the user types a number and hits ENTER, and the first scanf call reads the number and leaves the \n on the input stream. But then in the second scanf call, %c does not skip whitespace, so the "letter" it reads is the \n character.

在这种情况下,解决方案是显式强制默认情况下,%c 不会跳过空白。关于 scanf 的另一个鲜为人知的事实是,格式字符串中的空格并不意味着完全匹配一个空格字符,而是匹配任意数量的空格字符。 。因此,如果您将第二个程序更改为:

The solution in this case is to explicitly force the whitespace-skipping that %c doesn't do by default. Another little-known fact about scanf is that a space in a format string doesn't mean "match one space character exactly", it means "match an arbitrary number of whitespace characters". So if you change your second program to:

printf("Enter number....");
scanf("%d", &number);

printf("Enter letter...");
scanf(" %c", &letter);

现在,%c scanf 调用中,c>将跳过用户键入数字后剩下的 \n ,第二个 scanf 调用应该阅读它应该输入的字母。

Now, the space character in " %c" in the second scanf call will skip over the \n that was left over after the user typed the number, and the second scanf call should read the letter it's supposed to.

最后,要进行一些编辑。如果您认为这是一种奇怪的情况,如果您认为%c 的工作方式的例外情况有点奇怪,如果您认为这样做不应该那么难如果您认为我对正在发生的事情的解释比原本应该的要长得多且复杂得多,请先读一个数字,然后再写一封信,这是对的。 scanf 是C标准库中较丑陋的功能之一。我不知道有任何C程序员会用它做任何事情-我不相信我曾经用过它们。实际上,它的唯一用途是使开始使用C的程序员将数据导入他们的第一个程序,直到他们学习执行该任务的其他更好的方法,而这些方法不涉及 scanf

Finally, a bit of editorializing. If you think this is a bizarre situation, if you think the exception to the way %c works is kind of strange, if you think it shouldn't have been this hard to read a number followed by a letter, if you think my explanation of what's going on has been far longer and more complicated than it ought to have been -- you're right. scanf is one of the uglier functions in the C Standard Library. I don't know any C programmers who use it for anything -- I don't believe I've ever used it. Realistically, its only use is for beginning C programmers to get data into their first programs, until they learn other, better ways of performing that task, ways that don't involve scanf.

所以我对您的建议是不要花费太多时间试图让 scanf 工作或学习关于它的所有其他缺点。 (它有很多。)一旦您感到舒适,就开始学习其他更好的输入方法,并将 scanf 永远舒适地留在后面。

So my advice to you is not to spend too much time trying to get scanf to work, or learning about all of its other foibles. (It has lots.) As soon as you're comfortable, start learning about the other, better ways of doing input, and leave scanf comfortably behind forever.

这篇关于两次使用scanf()函数:在一种情况下有效,但在另一种情况下无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆