2.7、数据的输入

By | 2015年1月30日

在上文中,我们学习了使用printfputchar输出数据,现在我们就来看看如何输入数据。

printf、putchar很相似,我们可以使用scanf和getchar来输入数据

getchar的字面意思就是get(获取)一个char,这个函数他将返回一个整型的数据,这是你从屏幕中输入的字符的ascii码,你可以使用整型或者字符型来接收。

请尝试下面的程序

#include <stdio.h>

int main()
{
    char ch;
    ch = getchar();//用ch去接受字符
    putchar(ch);//将字符显示出来
    return 0;
}

请亲自运行这个程序。你会发现它启动后并不像我们之前的程序,黑色的窗口内一个字符也没有显示

什么东西都没有显示

什么东西都没有显示

当然,这是因为我们使用了一个getchar,它在等待我们输入数据。如果我们就这样瞄着屏幕哈气,那么程序也会不鸟你(除了光标还在一闪一闪的,告诉你“我正在运行”)

现在,请按下屏幕上任意一个字符键,切记是字符键(就是a-z,0-9和其他所有的标点符号)

2015-01-30 21 29 25

很明显,屏幕里出现了一个字符,他就是我们刚刚通过键盘输入的

但是如果你看懂了前一节的的话,或许会问到【你用putchar输出的字符呢】

答案是getchar还在等我们输入!

要验证这个很简单,我们只需要再按另一个键

输入1后也显示了出来

输入1后

你会发现它会跟在a后面显示出来,这说明getchar还在等待我们输入(难道getchar可以一次输入多个字符?可是我们只用了一个char变量去接受它啊)

【你骗我,你个坏淫!说好了输入字符的呢!】

我可没骗你,要让getchar得到字符,只需要你按一下回车键2015-01-30 21 39 37

程序就退出了,而且在第二行显示了我们一开始输入的字符a

为什么会这样呢。要说明白这个,就不得不讲到一个叫做“缓冲区”的东西了

如果把缓冲区放在本文中讲,就会显得太长。而且重点也比较分散、同时也加大了难度。于是我将它单独放到了一篇文章中 http://yangwang.hk/?p=315 。如果你比较急,可以现在把它看完。或者留在本篇文章看完后再浏览。如果你觉得内容太困难(新手理解起来确实有难度),往后放放也行,它并不会对我们后面的学习有太大的影响!

总之,我们只需要知道,直接从键盘中输入的数据,不会被getchar立即得到。而是等你在按下回车之时,getchar才会get到一个字符,然后将它传回来。

scanf

scanf就是scan(扫描)+format(格式化),即格式化输入函数

scanf的用法就要比getchar复杂多了。不过他和printf差不多,它们是一家子,一个是输入,一个是输出。

scanf的参数和printf长得也差不多(就像龙凤胎一样),他的参数也分两部分,一个是字符串类型的格式控制参数,在格式控制参数的后面,跟的是“可变”个数的保存数据的变量(参数个数根据格式控制参数而改变)

刚才的程序改为scanf后长这样

#include <stdio.h>

int main()
{
    char ch;
    scanf("%c", &ch);   //使用scanf输入一个字符
    putchar(ch);        
    return 0;
}

请尝试运行这个程序,他和上面的版本在操作上没有什么不同,如果你一股脑的输入数据而不按回车的话,scanf什么也得不到。

知道你按下回车的那一刻,scanf才会着手开始处理你输入的数据,并且将值保存在变量ch中。

getchar使用起来很简单,但是功能也很简单,它一次只能获取一个字符,而且还是ascii码。而scanf用起来似乎难度大一些,但是功能比getchar要强大得多。

我们现在把上面的程序中scanf那句抠出来放在这儿,来方便我们的讲解。

scanf("%c", &ch);

“%c”就是格式控制参数,它看起来和printf差不多,实际上他就是将printf反过来。printf打印数据到屏幕,scanf则从“屏幕”上(准确说是输入缓冲区)取回数据到变量。

%c这个占位符告诉scanf,我们需要输入的是一个字符型数据,不是十六进制整数,更不是十进制浮点数。

后面的ch则是保存输入数据的变量。这一切都和printf相同,除了ch前面多加了个&

&在c语言中是“取址符”,作用是获取一个变量的(内存)地址。

这就像你家的地址一样,通过这个地址,我可以找到(访问)你。

scanf就像一个送快递的,我们输入的数据就是快递。

当我们需要把快递送给xxx时,就需要在运单上填好xxx的地址,scanf这个快递员便会根据这个地址把快递放到xxx家。

如果你只写了收件人是xxx(写变量名),不给地址,那么快递员肯定会给你两巴掌。因为xxx是一个人,鬼知道他在哪儿!(变量名代表的是数值)

至于发快递的时候(printf输出的时候),就没有这么麻烦了。printf就像是一个收件的员工。你到快递网点发快递时,只需要把快件(数据)交给他就好了,鬼去管你家住哪儿(其实还是需要发件人地址,退回的时候用啦)。因此就用不着取址符。如果你在printf里用了取址符,那么它输出的就不是数据而是变量的地址了!

下表是scanf的部分占位符

字符 对应的数据类型 含义
i int 输入八进制、十六进制、十进制整数
d int 输入整型数值
o unsigned int 输入8进制整数
u
unsigned int 无符号10进制整数
x / X
unsigned int 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF(不输出前缀0x)
f(lf)
float(double) 单精度浮点数用f,双精度浮点数用lf
e / E
double 输入科学计数法表示的数,此处”e”的大小写代表在输出时用的“e”的大小写
g / G
double 同上
c
char 输入字符型
s / S
char * 输出字符串

请看下面的程序

#include <stdio.h>

int main()
{
    int intdata;
    double doubledata;
    scanf("%d%lf", &intdata, &doubledata);
    printf("%d\n%f", intdata, doubledata);
    return 0;
}

这个程序将输入一个int数据,和一个double数据,并且将它显示出来

使用时,先输入第一个数据(一个整数),然后按回车

接着输入第二个第二个浮点型数据,再按回车

2015-01-30 22 45 42

现在请自己写一个“计算”程序

输入两个浮点型数据,然后打印出他们的和

答案将在下一篇文章中揭晓

发表评论

电子邮件地址不会被公开。 必填项已用*标注