标题:关于标准库函数scanf
只看楼主
qfyzy
Rank: 2
等 级:论坛游民
威 望:1
帖 子:380
专家分:86
注 册:2008-2-17
结帖率:100%
 问题点数:0 回复次数:19 
关于标准库函数scanf
论坛上很多人对scanf的不太了解,导致程序出错,我想把scanf的具体用法贴出来,希望大家可以共同进步,有什么不对的地方可以提出来。
int scanf(char *format,...);
这应该是scanf的标准形式。先说说关于他的返回值的问题。
库函数几乎都是有返回值的,有些人可能很奇怪,怎么很少人用过scanf的返回值呢?
scanf会返回成功接收到的变量数量的值。比如scanf("%d",&j"),与scanf("%d=",&j),如果接受成功的话返回值都是1
我用如下语句作了测试
#include <stdio.h>
int main (){
    int j;
    printf ("%d",scanf("%d\n",&j));
    return 0;
}
如果你开始就输入回车,程序会继续等待你输入,因为在输入数字的时候,scanf会跳过空白字符。(the c programming language 上说,scanf实际上是用getchar()接受由数字组成的字符串,再转换成数字)
如果我输入ctrl-z(unix上是ctrl-d)则会返回-1(随编译器而定).这实际上就是常量EOF的值,也就是所谓的返回eof
如果我键入的不是数字返回值就是0。但是如果我输入浮点数,又会怎么样呢?
我举的例子中同样会返回1,但是缓冲区会留下垃圾,如果是scanf("%d%d",&a,&b);则会出错。
这是可以使用一个库函数fflush(stdin)来清除缓冲。不过貌似雨中飞燕大姐说这个用法是非标准的。K&R,只是说行为没有定义,但我们可以使用while((c=getchar())!='\n'&&c!=EOF);同样可以清除后面的垃圾
scanf的格式匹配还是比较简单,一定要记住的就是普通变量一定要加上&,否则编译器无法检测错误,但运行肯定会段错误。
    ┏━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ 代  码 │             意                          义             ┃
    ┠────┼────────────────────────────┨
    ┃   %a   │读浮点值(仅适用于 C99)                                  ┃
    ┃   %A   │读浮点值(仅适用于 C99)                                  ┃
    ┃   %c   │读单字符                                                ┃
    ┃   %d   │读十进制整数                                            ┃
    ┃   %i   │读十进制、八进制、十六进制整数                          ┃
    ┃   %e   │读浮点数                                                ┃
    ┃   %E   │读浮点数                                                ┃
    ┃   %f   │读浮点数                                                ┃
    ┃   %F   │读浮点数(仅适用于 C99)                                  ┃
    ┃   %g   │读浮点数                                                ┃
    ┃   %G   │读浮点数                                                ┃
    ┃   %o   │读八进制数                                              ┃
    ┃   %s   │读字符串                                                ┃
    ┃   %x   │读十六进制数                                            ┃
    ┃   %X   │读十六进制数                                            ┃
    ┃   %p   │读指针值                                                ┃
    ┃   %n   │至此已读入值的等价字符数                                ┃
    ┃   %u   │读无符号十进制整数                                      ┃
    ┃  %[ ]  │扫描字符集合                                            ┃
    ┃   %%   │读 % 符号(百分号)                                       ┃
    ┗━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
前面都很简单,%p,%n很少用到,跳过。要输入%必须要在前面再加一个%,
重点来谈谈%s和%[]。%s是读入一个数组,他与gets的区别就在于%s会以任何的空字符结束,而gets是回车结束。
同样%s前可以加数字,表示只读多少个。
ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:
    %[ABC]
使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。
 对于许多实现来说,用连字符可以说明一个范围。 例如,以下扫描集使 scanf() 接受字母 A 到 Z:
 %[A-Z]
 重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。
对于%[]还可以用^+任意字符(包括eof)来结束字符串的输入。比如%[^EOF]就是直到有EOF输入,字符串才中止。
但一定要记住就是c语言是缓冲输入,即使你%[^a],再你输入回车之前输入多少的a都是不可能结束的。
%s的输入会跳过空白字符,但是%c则不会。
这也就是
scanf("%d",&h);
scanf("%c",&c);
如果这写的话,变量c放的一定是回车。
如果想实现这种输入,可以在两个语句之间加入一个getchar(),他可以吃掉这个回车,
也可用scanf("%d %c",&h,&c);来做,再输入数字后加一个空格。就可以了
但千万别用scanf("%d\n",&h)!!!!!!!!k&r说的十分清楚,任何非格式化的字符都需要完全匹配。
意味着,只有输入数字后面再加\n才是合法的。
还有就是*加在任何项的前面表示该项不符值,别的就没什么好说的了
收到的鲜花
  • cosdos2008-03-09 22:42 送鲜花  6朵   附言:精品文章
  • 广陵绝唱2009-01-30 23:25 送鲜花  49朵   附言:好文章,爱编程,爱BCCN。 顶到前面吧, ...
搜索更多相关主题的帖子: scanf 库函数 quot 返回值 int 
2008-03-09 11:30
默默无纹
Rank: 1
等 级:新手上路
帖 子:45
专家分:0
注 册:2008-2-12
得分:0 
顶了,

从来怨天尤人每每自封为神
常怜众生如蚁不意身本凡尘
2008-03-09 15:07
☆Jony☆
Rank: 1
等 级:新手上路
帖 子:70
专家分:0
注 册:2008-2-22
得分:0 
很高兴能学到这么细节的东西!
加油阿!

☆滴水穿石☆水滴石穿☆
QQ:920633639
2008-03-09 16:26
zhuwei168
Rank: 1
来 自:东软信息学院
等 级:新手上路
帖 子:180
专家分:0
注 册:2008-2-13
得分:0 
虽然看得不是很懂但是顶了
2008-03-09 18:17
cosdos
Rank: 9Rank: 9Rank: 9
来 自:ShangHai
等 级:蜘蛛侠
威 望:6
帖 子:2109
专家分:1385
注 册:2007-6-19
得分:0 
学习了

—>〉Sun〈<—
2008-03-09 22:42
tinablock
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2008-3-19
得分:0 
好说法,受益了!
2008-03-19 13:12
hoodlum1980
Rank: 2
来 自:浙江大学
等 级:论坛游民
威 望:2
帖 子:289
专家分:23
注 册:2008-2-24
得分:0 
Read formatted data from the standard input stream.

int scanf(
   const char* format [,argument]...
);

int wscanf(
   const wchar_t* format [,argument]...
);
Parameters
format
Format control string.
argument
Optional arguments.
Return Values
Both scanf and wscanf return the number of fields converted and assigned; the return value does not include fields that were read but not assigned.

A return value of 0 indicates that no fields were assigned.

The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character.

Remarks
The scanf function reads data from the standard input stream stdin and writes the data into the location given by argument.

Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format.

If copying takes place between strings that overlap, the behavior is undefined.

The information here applies to the entire scanf family of functions, including the secure versions and describes the symbols used to tell the scanf functions how to parse the input stream, such as the input stream stdin for scanf, into values that are inserted into program variables.

A format specification has the following form:

%[*] [width] [{h | l | ll | I64 | L}]type

The format argument specifies the interpretation of the input and can contain one or more of the following:

White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.

Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in the input stream does not match, scanf terminates.

Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.

The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in the input stream; the matching characters in the input stream are scanned but not stored. If a character in the input stream conflicts with the format specification, scanf terminates, and the character is left in the input stream as if it had not been read.

When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.

An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.

Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.

The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.

An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.
2008-03-19 13:20
shilei525918
Rank: 1
等 级:新手上路
帖 子:18
专家分:0
注 册:2007-1-2
得分:0 
顶,十分感谢
2008-03-20 13:44
杨凯淇
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-3-26
得分:0 
顶了,好好看看
2008-03-26 12:46
mqh21364
Rank: 1
等 级:新手上路
帖 子:642
专家分:0
注 册:2008-2-28
得分:0 
但我们可以使用while((c=getchar())!='\n'&&c!=EOF);同样可以清除后面的垃圾
弱弱地问一句:怎么清除阿?覆盖????

前不见古人,后不见来者。念天地之悠悠,独怆然而涕下。
2008-03-28 09:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-202610-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.096396 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved