为什么scanf函数(QUOT;%D&QUOT,[...])不会消耗的'\\ n'?而scanf函数(QUOT;%C")呢? [英] Why scanf("%d", [...]) does not consume '\n'? while scanf("%c") does?
问题描述
这里,我看到了在接受的答案这条语句:
大部分的转换说明的跳过前导空白包括换行,但
%C
没有。
块引用>对于我来说,目前还不清楚这下不同行为的理由,我本来期望一个统一的一个(例如总是跳跃或从不)。
我来到这样的问题了一块C $ C $的C是这样的:
的#includestdio.h中诠释主要(无效){ 焦炭CH;
INT actualNum; 的printf(插入一个数字:);
scanf函数(%d个,&安培; actualNum);
//的getchar(); 的printf(插入字符:);
scanf函数(%C,&安培; CH); 返回0;
}交换这两个
scanf函数
取值可以解决问题,还有(评论)的getchar
,否则的'\\ n'
第一插入将由第二scanf函数
与%C
。我对GCC都在Linux和Windows的测试,该行为是一样的:
海湾合作委员会(GCC)4.7.2 20120921(红帽4.7.2-2)结果
版权所有(C)2012自由软件基金会,公司
这是自由软件;参见复印条件的来源。有否
保证;即使不是针对特定目的的适销。
块引用>我的问题是:为什么
%d个
和%C
表现不同w.r.t.的'\\ n'
在scanf函数
?解决方案从的马的嘴:
7.21.6.2 fscanf函数
...结果
5空白字符(S)组成的指令被读取输入到执行
第一个非空白字符(这仍然未读),或直到没有更多的字符可以
被读取。该指令永远不会失败。结果
...结果
7的指令,这是一个特定的转换阳离子科幻科幻德未列名一组匹配的输入序列,如
下面针对每个特定连接器描述。 A转换特定网络阳离子通过以下步骤执行:搜索结果
8输入空白字符(由isspace为
函数特定网络版)被跳过,除非
在特定网络阳离子包括[
,C
或N
特定连接器。
284)搜索结果
9的输入项目是从流中读取,除非特定网络阳离子包括N
特定连接器。 的
输入项目被定义为不超过输入字符序列最长
任何特定网络版场宽度,并且,或者是,一个匹配的输入序列pre网络的X.
285)
在第一个字符,如果有的话,之后的输入项保持未读。如果输入的长度
项是零,该指令失败的执行;这个条件是一个匹配失败,除非
最终OF-音响文件,编码错误,或从流读误差prevented输入,在这种
情况下,它是一个输入故障。
284)这些空白字符不是针对一个特定的编场宽度计算。结果
285)的fscanf推回至多一个输入字符到的输入流。因此,一些序列
可以接受的关于strtod,strtol将等等,都是不能接受的FSCANF。
块引用>重点由我补充道。
空格不是有效的整数字符串的一部分,所以它是有道理的
%d个
转换说明跳过任何前导空格。不过,空白可能是对自己有效,因此,它是有道理的%C
转换说明符的不的跳过它。根据以上第5条,如果你把一个空白的前
%C
指令格式字符串,所有领先的空白将被忽略:scanf函数(%C,&安培; CH);
Here, I saw this statement in the accepted answer:
Most of the conversion specifiers skip leading whitespace including newlines but
%c
does not.For me it is not clear the rationale under this different behaviors, I would have expected a uniform one (e.g. always skipping or never).
I came into this kind of problem with a piece of C code like this:
#include "stdio.h" int main(void){ char ch; int actualNum; printf("Insert a number: "); scanf("%d", &actualNum); // getchar(); printf("Insert a character: "); scanf("%c", &ch); return 0; }
Swapping the two
scanf
s solves the problem, as well as the (commented)getchar
, otherwise the'\n'
of the first insertion would be consumed by the secondscanf
with%c
. I tested on gcc both on linux and windows, the behavior is the same:gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.So my question is: Why does
%d
and%c
behave differently w.r.t.'\n'
inscanf
?解决方案From the horse's mouth:
7.21.6.2 The fscanf function
...
5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.
...
7 A directive that is a conversion specification defines a set of matching input sequences, as described below for each specifier. A conversion specification is executed in the following steps:
8 Input white-space characters (as specified by theisspace
function) are skipped, unless the specification includes a[
,c
, orn
specifier. 284)
9 An input item is read from the stream, unless the specification includes ann
specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence. 285) The first character, if any, after the input item remains unread. If the length of the input item is zero, the execution of the directive fails; this condition is a matching failure unless end-of-file, an encoding error, or a read error prevented input from the stream, in which case it is an input failure.
284) These white-space characters are not counted against a specified field width.
285) fscanf pushes back at most one input character onto the input stream. Therefore, some sequences that are acceptable to strtod, strtol, etc., are unacceptable to fscanf.Emphasis added by me.
Whitespace is not part of a valid integer string, so it makes sense for the
%d
conversion specifier to skip any leading whitespace. However, whitespace may be valid on its own, so it makes sense for the%c
conversion specifier to not skip it.Per clause 5 above, if you put a blank space in the format string prior to the
%c
directive, all leading whitespace will be skipped:scanf(" %c", &ch);
这篇关于为什么scanf函数(QUOT;%D&QUOT,[...])不会消耗的'\\ n'?而scanf函数(QUOT;%C")呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!