本文主要是介绍第三章 初窥天机之顺序程序设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在程序设计中有三种基本的结构,而正是这三种基本的结构组成了程序设计的主体。它们分别是:顺序结构,选择结构,循环结构。本章我们将会讲解有关顺序结构设计,并且以几个实际的函数作为实例,进行相关编程,让大家对顺序结构设计能够深刻的理解和掌握。
前面我们已经大概讲了一点printf函数的输出结果。其实printf函数还有很多的使用技巧,我们将会在本章进行更加详细的介绍。实际上在我们写代码时总是少不了程序的输入和输出。输入输出就像是一个数学函数,输入是变量,输出则是结果。但是在实际的程序设计中输入输出是有格式要求,我们可以按照我们想要的方式输出结果,比如在输入时只接受数字或字母,输出要求是金字塔或倒金字塔等。说了这么多,接下来让我们见证输入和输出函数的神奇吧!
本章我们主要会讲解三对输入输出函数和一对特殊的输入函数,三对输入输出函数分别是:printf和scanf函数、puts和gets函数、putchar和getchar函数。一对特殊的输入函数是:getche函数和getch函数。想知道它们有什么具体的效果和作用吗?请接着看。
3.1 顺序结构
顺序结构在程序设计中是最简单的,只需要按照问题解决的顺序写出相应的语句就行,它的执行顺序是自上而下,依次执行的。
为了更加直观的理解设计我们通常会使用流程图或者N-S图来显示程序运行的过程。不过我个人还是赞同使用流程图的,虽然N-S在很多方面比流程图效果要好。但是无论是在使用频率上,还是可理解上,我个人感觉还是流程图距离我们更近。好像最早应该高中时我们就已经开始接触流程图了,所以会有一种亲切感。

如图3.1所示,为顺序结构流程图。对应(a),首先执行“语句1”,然后执行“语句2”,最后执行“语句3”。对于现代的任何人来说,上学都有着美好的记忆,在学校我们学到了很多的知识,为我们将来的发展奠定了良好的基础。那么如图(b)就是上学的一个流程图。首先我们需要等待“录取通知”,一般情况下就是一个录取通知书了。然后我们知道录取之后,我们就需要“交学费”,交完学费,我们就可以等到开学“上学”了。对于图3.5中的(c)便是一个启动轿车的流程图了。首先我们需要给轿车点火启动,也就是“轿车点火”,启动轿车之后我们就需要“挂档”了,因为“挂档”之后轿车才会前行。
比如:
int a=1;
a++;
a += 6;
这就是一个顺序结构,首先定义一个变量a,然后执行a自加1,最后执行a加上6再赋值给变量a。
我们将用三个顺序结构实现的数据交换来进一步理解顺序结构。
【例3.1】顺序结构设计之三种数据交换方法。
解题思路:我们使用顺序结构实现三种数据的交换算法,一种是使用的加法运算,一种使用的是乘法运算,一种使用的是除法运算。注意:除法运算最好在整数类型下,否则容易出现错误。
编写程序:
#include <stdio.h>
int main()
{int a,b,temp;////方法1a = 13;b = 16;printf("a=%d, b=%d\n", a, b);temp = a;a = b;b = temp;printf("a=%d, b=%d\n", a, b);//////方法2a = 13;b = 16;printf("a=%d, b=%d\n", a, b);a = a+b;b = a-b;a = a-b;printf("a=%d, b=%d\n", a, b);//////方法3a = 13;b = 16;printf("a=%d, b=%d\n", a, b);a = a*b;b = a/b;a = a/b;printf("a=%d, b=%d\n", a, b);return 0;
}
运行结果:
a=13, b=16
a=16, b=13
a=13, b=16
a=16, b=13
a=13, b=16
a=16, b=13
Press any key to continue
程序分析:程序第1行为下面printf函数的头文件,第2行为程序的入口main函数,任何C语言程序都会需要这个函数。int表示程序返回值为整数,我们在第34行发现程序返回0,就是说程序正常结束。要编写的程序都需要卸写在花括号之间,即第3~35行之间。第4行定义了三个变量。第5~6行是用‘\\’注释。第7~8行为变量赋值,分别把13赋值给a,把16赋值给b。第9行输出变量a,b的值。第10行把a中的值13赋值给temp,此时a和temp的值一样。第11行把b的值赋值给a,a原来的值13就会被b中的值16所覆盖,即a成为16。第12行把temp的值赋值给b,b原来是16就会被temp中的13所覆盖,b就变成了13。现在a由原来的13变成了16,b也由原来的16变成了13。因此实现了数据交换。第13行输出交换后的a,b值。剩余的程序用这样的方式即可分析,此处就不再赘述。
如上为三种基本且经典的数据交换方法,另外还有其他的方法实现数据的交换,比如位运算等。大家可以从网络上查到大量相应的信息。
3. printf函数
3.2.1 printf函数的说明
printf函数是格式输出函数,一般用于向标准输出设备按规定格式输出信息。printf函数是被定义在头文件stdio.h里的,因此在使用时需要加上#include <stdio.h>。
3.2.2 printf函数格式
表3.1列举了printf函数的语法要点。通过该表我们就可以查的printf函数的使用规则。比如所需头文件是#include <stdio.h>,返回值是void。void表示为空。
所需头文件 | #include <stdio.h> |
函数原型 | void printf(const char *format, ...); |
函数输出格式 | format:为函数输出的格式字符串 |
函数传入值 | 传入值根据具体的format中要求的格式信息输入 |
函数返回值 | void |
“格式信息”参数包含三种对象类型的字符串:
- 无格式字符串复制到输出流。
- 转换规范,每个规范导致在参数列表中检索一个或多个项。
- 转义序列。
上面这三种说法是不是太文艺了呢?不用管它,我们稍后会以一个实际代码实例来进行详细的说明。此处留作将来查询用。
【例3.2】printf函数的基本使用。
解题思路:编写该程序的主要目的就是为了帮助大家了解类似表3.1中的信息并如何使用表中所给的信息进行编程。
编程程序:
#include <stdio.h>//头文件
int main()//函数入口,main函数
{printf("Hello friends,");//printf函数基本格式,不带参数printf("hello %d", 1);//printf函数基本格式,带一个常量参数return 0;//说明程序正常结束返回0
}
运行结果:
Hello friends,hello 1Press any key to continue
程序分析:首先我们观察表3.1,第一行是printf所需头文件为#include <stdio.h>,就是在要求在使用printf函数时需要写上这个头文件。正如我们程序中第一行所写,就是头文件。然后任何程序都需要一个入口函数就是main函数,main函数下用一对大括号括起来所有程序就是我们书写程序的主体框架,是我们写程序的基本框架。在大括号里面才是我们要写的程序。表3.1中第二行说函数原型,就对应程序第4~5行。在printf函数原型中有省略号表明参数可有可无。这就是程序中第4~5行的区别,第4行没有参数,第5行有参数1。“%d”就是把1保存到双引号的字符串中。后面会介绍“%d”及相关信息的介绍。函数的传入值就是1。传入值不仅可以是常数也可是是变量或者字符串。相应的接受的类型“%d”,也需要做对应的改变。返回值是void,表示返回值为空,在编写程序中写成我们程序第4~5行的无返回值的格式就行。
3.2.3 输出数据格式的规定
什么是输出格式?输出格式就是按照一种什么类型的样式输出,比如输出整数,输出字符,输出十六进制数或八进制数等。
通常意义上的“格式信息”的格式如下:
%[flags][width][.prec][F|N|h|l]type
看上去都是英文,不好理解。看看汉语是如何表示的:
%[标志][输出最小宽度][.精度][长度]类型
格式字符串都是以%开头,后面接着是“标志”,即“+”或“-”。如果程序中有“精度”,则“精度”前面的小数点必须有。“类型”就是输出的格式信息,比如十进制输出,类型就是d。字符输出,类型就是c。而“[]”是作为可选项来使用的,就是说凡是用“[]”表示的格式都是可选的,可有可无。其他变成语言中也有类似的情况。具体表示方式和详细信息请参考下面四部分和代码讲解。
- 格式化字符串中允许使用的修饰符
接下来这几部分我们将会对应上面“格式信息”中的格式进行详细的说明。那么此部分我们将会说明“格式信息”中的“标志”、“输出的最小宽度”、“精度”、“长度”以及扩展且常用的信息“ ”(空格)、“0”、“#”。详细信息参考表3.2格式化字符串中允许使用的修饰符。
字符 | 字符名称 | 说明 | 范例 |
- (标志) | 负号 | 设置左对齐。但总宽度必须比实际宽度大才有效 | %-4d %-6.4f |
+ (标志) | 正号 | 默认为正号,可以不写。若设定的宽度比实际宽度大,数据向右看齐 | %+4d(或%4d) %+6.4f(或%6.4f) |
width (最小宽度) | 宽度 | 设置数据显示的宽度。如果宽度比数值本身宽度小,则以实际宽度显示。若输出含有小数部分,则宽度包括整数位数、小数点、小数位数以及正负号 | %4d %6.4f |
. | 小数点 | 设置小数 | %6.4f |
prec (精度) | 小数点后面的位数 | 设置小数点后面的位数:
|
|
(空格) | 空格 | 若正数前面加空格,则显示空格。若负数前面加空格,则显示负号 | printf("% 4d", 43); 结果: 43 printf("% 4d", -43); 结果:-43 |
0 | 数字零 | 将输出的前面补上0,直到占满指定列宽为止(不可以搭配使用“-”) | printf("%04d", 43); 结果:0043 |
# | 井号 |
|
结果:053 2. printf("%#e", 43.3); 结果:4.330000e+001 3. printf("%#g", 43.3); 结果:43.3000 |
注:表格正文第六行是空格,所以好像感觉不到任何效果。该按键就是键盘正下面那个长键。
- 规定数据的格式
此处我们讲解数据的格式,也就是上面“格式信息”中对应的“类型”信息。如果我们想要使用printf输出一个十进制整数,该怎么办呢?一个字符或字符串呢?这些都是由数据格式来控制的,因此可见我们“类型”的重要性。
另外从“格式信息”中我们也可以看出“类型”的重要性,在“%”之后除了“类型”外,其他的都是可有可无的可选项。而“类型”却是必须有的。
在我们的“类型”中又以“%d”、“%f”、“%lf”、“%c”、“%s”更为常用,所以这几种类型大家要重点记忆。详细的数据格式大家参考表3.3即可。
数据类型 | 字符 | 对应数据类型 | 含义 |
整数 | d/i | int | 接受整数值并表示有符号的十进制整数,i是老式的写法 |
o | unsigned int | 无符号的八进制整数(不输出前缀0) | |
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 | 使用以上两种中最短的形式,使用同%e和%E | |
字符或字符串 | c | char | 字符型。把输入的数字按照ASCII码转换为对应的字符 |
s/S | char */wchar_t * | 字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符) | |
其他类型 | p | void * | 以十六进制形式输出指针 |
n | int * | 到此字符之前为止,一共输出的字符个数,不输出文本 | |
% | 无输入 | 不进行转换,输出字符‘%’(百分号)本身 | |
m | 无 | 打印errno值对应的出错内容,(例: printf("%m\n");) |
注:%g,%G在小数点位数四位或指数大于等于精度时用%e、%E,否则用%f。
【例3.3】经过以上的格式输出的了解,对应的编写相应的程序代码。
程序分析:为了便于理解上表中各个格式的使用,我们采用一个实际的实例来进行说明,帮助大家理解。抽象具体化。
编写程序:
#include <stdio.h>//头文件
int main()//main函数
{char c,s[20]="Hello world";//字符与字符串变量定义及初始化int a=1234;//整数变量定义及初始化double f=3.141592653589;//双精度浮点数变量定义及初始化double x=0.12345678987654321;//双精度浮点数变量定义及初始化c='\x41';//字符初始化printf("a=%d\n",a); /*结果输出十进制整数a=1234*/printf("a=%u\n",-a); /*结果输出无符号的十进制整数a=4294966062*/printf("a=%6d\n",a); /*结果输出6位十进制数a=1234*/printf("a=%06d\n",a); /*结果输出6位十进制数a=001234*/printf("a=%-4d\n",a); /*输出左对齐4位十进制整数a=1234*/printf("a=%o\n",a); /*结果输出八进制整数a=2322*/printf("a=%x\n",a); /*结果输出十六进制整数a=000004D2*/printf("a=%p\n",a); /*输出地址a=06E4*/printf("f=%f\n",f); /*输出浮点数f=3.141593*/printf("f=%6.4f\n",f); /*输出6位其中小数点后4位的浮点数f=3.1416*/printf("f=%*.*f\n", 6, 4, f);/*与printf("f=%6.4f\n",f);类似*/printf("x=%lf\n",x); /*输出长浮点数x=0.123457,因为原本x=0.1234567,而最后一位7需要四舍五入,所以把小数点后第六位的6变成7*/printf("x=%18.16lf\n",x);/*输出18位其中小数点后16位的长浮点数x=0.1234567898765432*/printf("x=%e\n", x); /*以科学计数法表示,输出为x=1.234568e-001*/printf("x=%E\n", x); /*以科学计数法表示,输出为x=1.234568E-001*/printf("c=%c\n",c); /*输出字符c=A*/printf("c=%x\n",c); /*输出字符的ASCII码值c=41*/printf("s[]=%s\n",s); /*输出数组字符串s[]=Hello world*/printf("s[]=%6.9s\n",s);/*输出最多9个字符的字符串s[]=Hello wor*/printf("s=%p\n",s); /*输出数组字符串首字符地址s=0012FF30*/return 0;//程序正常结束返回0
}
运行结果:
a=1234
a=4294966062
a= 1234
a=001234
a=1234
a=2322
a=4d2
a=000004D2
f=3.141593
f=3.1416
f=3.1416
x=0.123457
x=0.1234567898765432
x=1.234568e-001
x=1.234568E-001
c=A
c=41
s[]=Hello world
s[]=Hello wor
s=0012FF30
Press any key to continue
程序分析:程序第1行为头文件,应为我们使用了pintf函数,所以需要此头文件。第2~3行以及第30~31行为程序基本的框架。第4~7行为各种类型变量的定义以及初始化。第8行给字符变量赋值为十六进制的数据‘\x41’。第9~28行就对应表3.3的数据格式。在此处需要注意的是第10行,由于输出格式是无符号的整数,但是却接受了一个负数,所以就会造成程序中所示的输出结果。其中‘\n’表示换行,我们将会在下面的部分讲解。
三.F|N|h|l
我们已经在前两部分说明了“格式信息”中除“长度”以外的所有信息格式。对于“长度”信息我们也会做一个简短的介绍。
表示指针是否是远指针、是否是近指针、是否是整数、是否是长整数。
F:远指针
N:近指针
h:短整数(short int)
l:长整数(long int)
注:对于长整数l,此处如果与d搭配为%lld,则为long long int(C99),与f搭配为%llf则为long double(C99)。
四.转义字符
既然上面三部分都已经讲完了“格式信息”,那为什么还有这一部分呢?那是因为当我们解决了温饱问题,该想想小康社会了。哈哈。上面三部分的确已经对“格式信息”做了简要讲解,那只是满足了基本的需求,只解决了温饱问题而已。如果要求你一行一行的输出信息,你会怎么办?你可能回想我把一行一行的填满数据,不就是一行一行的输出了吗!那要是不让你填满一行就输出下一行呢?这个怎么办?这就需要我们用“转义字符”来步入“小康社会”。
什么是转义字符?就是通过添加一个‘\’与ASCII表中的一个字符组合而成。比如‘\n’,表示换行。同时“\”后面组合的字符并不是它在ASCII表中的的含义。此点需要大家注意。
转义字符会在字符串中自动转换为相应操作命令。具体如表3.4转义字符所示。表中所示转义序列中的字符,看上去像是两个或多个字符的组合,其实就是一个字符。
转义序列 | 说明 | 转义序列 | 说明 |
\n | 换行 | \f | 换页 |
\a | 响铃 | \b | Backspace |
\r | 回车 | \0 | 空字符(数值为0) |
\t | 水平制表符 | \v | 垂直制表符 |
\’ | 单引号 | \” | 双引号 |
\\ | 反斜杠 | \? | 文本问号 |
\ooo(例如\043) | ASCII字符(OCX) | \xhh(例如\x43) | ASCII字符(HEX) |
\xhhhh | 宽字符(两字节HEX) | \ddd | ASCII字符(OCT) |
在实际的使用中我们使用频率较多的几个转义字符是:‘\n’、‘\r’、‘\t’、‘\’’,‘\”’、‘\\’等几种形式。请大家重点记忆。
使用转义字符是有以下几点需要注意的要点:
- 转义字符只能使用小写字母。
- 转义字符‘\0’表示空字符NULL,它的值是0,对应的ASCII值是48。所以空字符‘\0’不是字符‘0’。且空字符(ASCII码值48)也不等于空格字符(ASCII码值32)。
- ‘\v’垂直制表符和‘\f’换页符对屏幕没有任何影响,影响打印机的响应操作。
- 如果反斜杠‘\’和其之后的字符不构成转义字符,则因‘\’不起转义作用而被忽略。
- C语言中不可打印的字符通常使用转义字符。
【例3.4】转义字符的使用。
解题思路:通过一个简单的实例加深对转义字符的理解。参考转义字符的注意要点,我们就知道有些转义字符对屏幕没有任何影响等原因,我们就不再在程序中写出事例。另外在每一行程序结束时,添加换行符‘\n’,为了便于观察。大家需要注意。
编写程序:
#include <stdio.h>//头文件
int main()//main函数
{printf("Hello C Program\n");//转义字符\n,表示换行printf("Hello C\a Program\n");//转义字符\a,表示响铃printf("Hello C\b Program\n");//转义字符\b,表示退格键,删除光标前一个字符printf("Hello C\r Program\n");//转义字符\r,表示回车printf("\tHello C Program\n");//转义字符\t,表示水平制表符printf("Hello C\0 Program\n");//转义字符\0,表示空字符printf("Hello \'C\' Program\n");//转义字符\',表示单引号printf("Hello C \"Program\"\n");//转义字符\",表示双引号printf("\\Hello C Program\\\n");//转义字符\\,表示反斜杠printf("\?Hello C Program\?\n");//转义字符\?,表示文本问号return 0;//正常返回0
}
运行结果:
Hello C Program
Hello C Program
Hello Program
Program
Hello C Program
Hello CHello 'C' Program
Hello C "Program"
\Hello C Program\
?Hello C Program?
Press any key to continue
程序分析:第1~3行以及程序最后2行不再解释,如果忘记什么意思,看之前的代码示例。第4行我们使用的转义字符是‘\n’,就是换行转义。程序运行结果中第一行,我们看到在输出“Hello C Program”字符串之后,并没有填充整个一行数据,就直接换行了。这就是转义字符中换行的作用。第5行转义字符是‘\a’,表示响铃。第6行转义字符是‘\b’,表示退格,功能是删除该转义字符相邻的前一个字符。在运行结果中就会出现只输出“Hello Program”,少了字符‘C’,这就是转义字符‘\b’的作用。第7行转义字符‘\r’,表示回车。运行结果第三行只出现了该转义字符后面的字符串。第8行转义字符为‘\t’,该转义字符作用是跳到下一个制表符的位置,一般占用8位。该转移字符还有对齐的作用。第9行是转义字符‘\0’,表示空字符。printf函数遇到到‘\0’就会结束输出,导致‘\n’并没有实现换行的作用。同时下一次输出的结果,会在上一次输出结果的末尾输出。所以出现了第六行的运行结果。第10~13行分别是转义字符‘\’’、‘\”’、‘\\’、‘\?’对应的输出结果分别是’’、‘”’、‘\’、‘?’。简单说,就是‘\’后面的那一个字符。程序中使用两个相同的转义字符,为了在运行结果中便于观察。
经过上面对printf函数的讲解我们应该已经掌握了printf函数的使用,如果对此还是有什么不解,再回去看看。下面就让我们使用printf函数来两个开胃菜吧!
【例3.5】输出一个正方体,并且在正面显示hello world。
解题思路:我们使用printf函数一行一行输出对应的图形边界信息。
编写程序:
#include <stdio.h>
int main()
{printf(" ________________\n");printf(" / /|\n");printf(" / / |\n");printf("|---------------| |\n");printf("| | |\n");printf("| hello world | |\n");printf("| | /\n");printf("|_______________|/\n");return 0;
}
运行结果:
【例3.6】输出驼羊的图像。
解题思路:在网站上我们会经常看到各式各样的图像,驼羊就是其中一种,下面我们输出的就是用printf函数输出驼羊外形。
编写程序:
#include <stdio.h>
int main()
{printf("┏┛┻━━━┛┻┓\n");printf("┃|||||||┃\n");printf("┃ ━ ┃\n");printf("┃ ┳┛ ┗┳ ┃围观是一种态度\n");printf("┃ ┃\n");printf("┃ ┻ ┃\n");printf("┃ ┃围观是为了提高知名度\n");printf("┗━┓ ┏━┛\n");printf(" ┃ ┃ \n");printf(" ┃ ┃ \n");printf(" ┃ ┃ \n");printf(" ┃ ┃ \n");printf(" ┃ ┗━━━┓\n");printf(" ┃ ┣┓\n");printf(" ┃围观专用宠物 ┃\n");printf(" ┗┓┓┏━┳┓┏┛\n");printf(" ┃┫┫ ┃┫┫\n");printf(" ┗┻┛ ┗┻┛\n");return 0;
}
运行结果:
看到上面两个程序输出的图形是不是很激动呢?没想到我们用printf函数就能玩出花样来。程序的世界魅力无穷,要想探索更多的未知,那就接着学习,提高实力,等我们一剑封江湖。努力!!!
3.3 scanf函数
3.3.1 scanf函数的说明
scanf函数是格式输入函数,即按用户指定的格式从标准输入流stdio(标准输入设备,一般是键盘)中把数据输入到指定的变量中去,按照要求的格式读入一个或多个数据,并保存到对应地址的变量中。
3.3.2 scanf函数格式
上一节我们讲解了输出函数printf,这一节我们讲解输入函数scanf。因为成双成对比较对称嘛!printf函数负责输出数据,scanf函数就是负责输入数据了。如表3.5所示列举了scanf函数的语法要点。
所需头文件 | #include <stdio.h> | |
函数原型 | int scanf(const char *format, ...); | |
函数传入值 | 函数传入值由format中要接受的类型传入 | |
函数返回值
| 成功 | 正确输入参数的个数 |
失败 | 0 或EOF |
scanf函数执行成功返回赋值的数据项数,失败出错时返回EOF。
【例3.7】scanf函数介绍。
解题思路:经过表3.5scanf函数语法要点的讲解,我们对scanf函数有一个大概的认知,现在通过代码的编写可以使大家能够轻松学会scanf函数的使用。
编写程序:
#include <stdio.h>
int main()
{int cnt = 0;int a,b;cnt = scanf("%d", &a);printf("成功输入一个变量时,scanf返回值个数:%d\n", cnt);cnt = scanf("%d %d", &a, &b);printf("成功输入两个变量时,scanf返回值个数:%d\n", cnt);cnt = scanf("%d", &a);//此处输入字符串printf("错误输入变量时,scanf返回值个数:%d\n", cnt);fflush(stdin);//后面将会介绍cnt = scanf("%d", &a);//输入Ctrl+z,然后按回车printf("出现EOF的情况,scanf返回值个数:%d\n", cnt);return 0;
}
运行结果:
32
成功输入一个变量时,scanf返回值个数:1
32 34
成功输入两个变量时,scanf返回值个数:2
right
错误输入变量时,scanf返回值个数:0
^Z
出现EOF的情况,scanf返回值个数:-1
Press any key to continue
程序分析:首先我们观察表3.5,scanf的头文件是#include <stdio.h>,所以我们程序第1行为#include <stdio.h>。第2~3行以及第15~16行为程序的基本框架,不在过多介绍。程序第4~5行是变量的定义及初始化。观察表中scanf函数的返回值为int型,所以第6行用scanf函数给整型变量a赋值后,返回一个整数,即输入参数的个数。显然我们输入的变量是一个,所以返回整数应该为1,如运行结果第1~2行所示。我们用符号‘&’表示取地址,就是从键盘中读取一个整数,放到名字为a的内存地址。同样在程序第8行,两个变量a和b被成功读入,则返回值为2。程序第10行,由于要求输入整型变量,而输入的却是字符串“right”,不能成功被读取,所以变量就是0。第12行fflush函数的功能为清空读写缓冲区,我们会在后面介绍。第13行我们输入ctrl+z后回车,就会出现运行结果中所示的结果。
注意:
在函数返回值失败时,返回的0或者EOF分别表示:
0:用户输入的不匹配,无法正确输入任何值。
EOF:定义在#include <stdio.h>,通常值为-1。表示输入流已经结束。在Windows平台下,按Ctrl+z,会出现一个^Z,表示输入结束。就会输出-1,即EOF,详情请看代码。
3.3.3 scanf函数各种类型输入
有输出格式就有输入格式,这一节中我们将会详细介绍各种类型的输入格式。由于输入格式的语法方式与printf函数类似,因此我们后面讲到相应的语法时,大家可以结合前面的printf函数语法的思想来学习scanf函数的语法。
实际上,scanf函数的格式信息和printf函数的格式信息相同,谁让他们是一对呢!所以此处我们贴出的scanf函数格式信息,也是printf函数的格式信息。其“格式信息”的格式如下:
%[flags][width][.prec][F|N|h|l]type
同样汉语的表示比如下:
%[标志][输出最小宽度][.精度][长度]类型
如果大家忘记了“格式信息”中各项表示的具体含义,还请大家返回到前面的scanf函数的定义来再次加深理解。而我们将会具体讲解scanf函数各种类型的输入。使大家能够轻松理解。
一:scanf函数整型输入
函数的整型输入,就是接受各种类型的整数。比如长整型,短整型,整型,无符号的整型等整型类型。另外大家需要注意的是此处的语法表示就是3.3.3中的具体化。后面的部分也是这样,需大家谨记。
语法:%[*][width][l|h][d|u|o|x]
其中,[]表示:可选项,width表示:指定输入数据所占宽度。l表示:输入长数据,是长度修饰符。h表示:输入短数据,也是长度修饰符。d,u,o,x分别表示:十进制整数输入,无符号十进制整数输入,八进制整数输入,十六进制整数输入。
“*”表示该输入项读入后不赋予任何变量,即跳过该输入值。
【例3.8】scanf函数整型输入
解题思路:由于scanf函数和printf函数是两个对应的函数,所以数据的修饰符、数据格式以及转义字符等都是类似的,大家可以参考表3.2,表3.3和表3.4。
编写程序:
#include <stdio.h>
int main()
{long a;//定义一个长整型变量short b;//定义一个短整型变量int c,d,e;//定义三个普通整型变量//分别按照长整型,短整型,无符号整型,八进制,十六进制格式输入scanf("%ld%hd%2u%o%x", &a, &b, &c, &d, &e);//输出结果printf("a = %d, b = %d, c = %d, d = %d, e = %d\n", a, b, c, d, e);return 0;
}
运行结果:
111 112 113
114 115
a = 111, b = 112, c = 11, d = 3, e = 276
Press any key to continue
程序分析:有很多不理解的人就会对这样的一个结果感到疑惑,接下来咱们就好好分析一下这样的结果吧。首先输入111后,111会自动保存到长整型变量a中;然后输入空格后,再输入112,则112会保存到短整型变量b中;之后输入了两个空格加一个tab制表符,再输入113,此时需要注意,整型变量c接收的是2个长度的无符号的整型,所以就会有c = 11这样一个结果;那为什么d = 3呢?这是因为c取113的两位数,造成3被整型变量d接受,以八进制的形式保存,所以输出的结果d = 3实质上是八进制的3,因为我们是以“%o”的格式接受数据。最后回车,再输入114,一个tab制表符和115,回车程序输入结束。可是为什么e = 276呢?其实与d = 3类似,因为114被整型变量e所接收,并以十六进制的形式保存到内存中,所以十六进制的114,就是十进制的276。由于115没有变量接收,编译器自动舍弃。
使用scanf需要注意一下两点:
- scanf读入一组整数时,会自动跳过空格、tab和回车符,寻找下一个输入域。每个输入域都是由一串连续的非空白字符的整型数据。
- 格式信息中除了要有以%开始的字符转换说明,还可以有普通的字符或字符组合。这些字符或字符组合是限制使用者输入数据格式使用的,并不在屏幕上显示。
二:scanf函数浮点数输入
函数的浮点数输入,就是接受各种类型的浮点数。最常用的浮点数就是单精度浮点数和双精度浮点数两种类型。下面看一下浮点数输入的格式。
通常意义上的“格式信息”的格式如下:
语法:%[+][-][width][.prec][f|e|g]
在标准C语言中有两种浮点数:单精度浮点数(float)和双精度浮点数(double)。
例如两种浮点数变量的定义:
float f;
double d;
单精度浮点数和双精度浮点数在计算机中的表示形式是非常类似的,只是所占用的二进制位数不同而已。因此,这两者对应的有效精度和取值范围是不同的。
单精度浮点数通过输入转移字符%f或%e来接受,前提定义float类型的变量。双精度浮点数通过输入转移字符%lf或%le来接受。
类型 | 占字节数 | 数值范围 | 十进制精度位数 |
float | 4 | -3.4e-38~3.4e38 | 6~7 |
double | 8 | -1.7e-308~1.7e308 | 14~15 |
【例3.9】scanf函数浮点输入。
解题思路:上面理论讲了很多,此程序就是讲解float和double的具体使用,和对应区别。
编写程序:
#include <stdio.h>
int main()
{float f;double d;printf("float占%d字节, double占%d字节\n", sizeof(float), sizeof(double));scanf("%f", &f);printf("%f\n", f);scanf("%lf", &d);printf("%lf\n", d);return 0;
}
运行结果:
float占4字节, double占8字节
123.456789876
123.456787
123.456789876
123.456790
Press any key to continue
程序分析:同样程序第1~3行,11~12行不在讲解。第4~5行分别是float和double的变量定义。第6行输出float和double各占字节数,运行结果发现float占4个字节,double占8个字节,这与表3.6中“占字节数”对应相同。注意此处我们用sizeof来测量变量所占字节数,该函数在程序编写中会被经常用到,请牢记。具体sizeof的语法要点,请参考表3.7。第7~8行和第9~10行分别是float和double的输入输出。
注意:sizeof是一个宏。是判断数据类型长度符的关键字。头文件是stddef.h,返回值类型为size_t。size_t类型就是无符号的整型。
三: scanf函数字符与字符数组输入
单字符语法:%[*]c
字符串语法:%[*][width]s
C语言中的char类型表示一个字符。那么如何表示一串字符呢?这就会引用字符串数组。一维字符串数组里面存放的是单个字符的序列。形如:char arr[12] = {'h','e','l','l','o',' ','w','o','r','l','d'}。此处会注意到字符串序列只有11个,而申请的字符串长度却是12个?细心的同学会发现,此处在输入时不会出现问题,但是在输出时就会发现输出hello world之后出现了乱码。因为无论是字符串常量还是字符串变量,在结束时都需要隐藏字符来结束,而多出来的第12位,也就是下表为11的那一位,程序会自动添加一个隐藏字符,也就是空字符。
【例3.10】scanf函数字符输入
解题思路:参考例3.7的解题思路即可。
编写程序:
#include <stdio.h>
int main()
{char c,arr[16];scanf("%c", &c);//字符输入printf("%c\n", c);fflush(stdin);/*清空缓冲区*/scanf("%s", arr);//字符串输入printf("%s\n", arr);fflush(stdin);return 0;
}
运行结果:
w
w
ds3ds
ds3ds
Press any key to continue
程序分析:程序第4行是字符变量c和字符数组arr的定义。第5行读入一个字符保存到内存地址为‘c’的变量中。第7行清空输入缓冲区下面会详解。第8行从键盘中读取一个字符串,保存到arr字符数组中,但是读取字符的长度不能超过arr定义的长度16。如果超过,超过部分会自动舍去。另外我们发现此处并没有使用取地址符‘&’,这是因为数组名又可以表示这个数组的开始地址。
fflush(stdin)功能:清空输入缓冲区。一般使用的目的是确保不应现后面数据的读取,如程序中就是避免上次输入字符对本次再输入字符的影响。如果没有fflush(stdin)函数就有可能造成上一次输入缓冲区的数据没有被上一次读取完,而被下一次的读取获得,影响最终结果。同学们可以尝试去掉fflush(stdin)函数,并且在第一次输入一个字符串,就会理解的更透彻。详细的fflush函数信息请查看表3.7。
stdin:标准输入,std即standard(标准),in即input(输入)。一般指键盘输入到缓冲区的数据。
注意:
除了stdin之外还有stdout,stderr。内核进程会打开三个流:0,1,2。分别代表stdin,stdout,stderr。
stdout:标准输出。是程序写入其输出的位置。缺省情况下,进程将stdout写到终端屏幕上。
stderr:标准出错。是程序写入起错误消息的位置。缺省情况下,进程将stderr写到终端屏幕上。
所需头文件 | #include <stdio.h> | |
函数原型 | int fflush(FILE *stream); | |
函数传入值 | stream是要冲洗的流 | |
函数返回值 | 成功 | 0 |
失败 | EOF |
如果大家想要更深入的了解fflush函数的使用,请自行学习。知识是靠自己的积累,成功是靠自己的努力。加油!!!
3.3.4 scanf函数特殊使用
在学习C语言时,通过scanf的特殊使用,会为程序增色不少,提高程序设计的效率,进而写出优美的程序算法。
如果我们输入一个规定长度的整数,应该怎么办?
如果我们输入一个规定长度的浮点型,应该怎么办?
如果我们输入一个规定长度的字符串时,应该怎么办?
如果我们只接受字母或者数字呢?
如果我们只接受规定长度的字母或者数字呢?
如果我们只有当读入某一个字符时才结束输入呢?
...
或许你认为这会非常的容易,如果要求只能使用scanf实现以上功能呢?
由此引入scanf的特殊用法:
scanf("%nd", &a);表示至多接受n位整数数据
scanf("%nf", &d);表示至多接受n位浮点型数据
scanf("%ns", arr);表示至多接受n位字符串类型数据
scanf("%[a-z]s", arr);表示只接受a-z的小写字母,遇到非a-z的字符结束
scanf("%[A-Z]s", arr);表示只接受A-Z的大写字母,遇到非A-Z的字符结束
scanf("%[a-zA-Z]s", arr);表示只接受a-z的小写字母和A-Z的大写字母,遇到非a-z和 A-Z的字符结束
scanf("%[0-9]s", arr);表示只接受0-9的字符,遇到非0-9的字符结束
scanf("%n[0-9]s", arr);表示至多接受n位的0-9的字符,或者遇到非0-9的字符结束
scanf("%[^=]s", arr);表示读任意多个字符,直到遇到"="停止
scanf("%n[^=]s", arr);表示在遇到"="停止前至多读入n个字符
scanf("%[^\n]%*c", arr);表示当读入回车后结束字符串输入
...
当然还可以经过以上输入格式的各种组合,来获取更多种输入方式,此处不再赘述,请同学们自行学习。
【例3.11】多种格式输入。
解题思路:在此程序中我们会重点讲解一些scanf函数的使用技巧。这样在我们以后的编程中就会大大的提高编程的效率和正确性。废话不多说,直接上程序。
编写程序:
#include <stdio.h>
int main()
{char arr[1024];int a;double d;scanf("%4d", &a);/*至多接受4位整数数据*/printf("%d\n", a);fflush(stdin);/*清空缓冲区*/scanf("%6lf", &d);/*至多接受6位浮点型数据*/printf("%lf\n", d);fflush(stdin);scanf("%4s", arr);/*至多接受4位字符串类型数据*/printf("%s\n", arr);fflush(stdin);scanf("%[a-z]s", arr);/*只接受a-z的小写字母,遇到非a-z的字符结束*/printf("%s\n", arr);fflush(stdin);scanf("%[A-Z]s", arr);/*只接受A-Z的大写字母,遇到非A-Z的字符结束*/printf("%s\n", arr);fflush(stdin);scanf("%[a-zA-Z]s", arr);/*只接受a-z的小写字母和A-Z的大写字母,遇到非a-z 和A-Z的字符结束*/printf("%s\n", arr);fflush(stdin);scanf("%[0-9]s", arr);/*只接受0-9的字符,遇到非0-9的字符结束*/printf("%s\n", arr);fflush(stdin);scanf("%6[0-9]s", arr);/*至多接受6位的0-9的字符,或者遇到非0-9的字符结束*/printf("%s\n", arr);fflush(stdin);scanf("%[^=]s", arr);/*读任意多个字符,直到遇到"="停止*/printf("%s\n", arr);fflush(stdin);scanf("%4[^=]s", arr);/*在遇到"="停止前至多读入4个字符*/printf("%s\n", arr);fflush(stdin);scanf("%[^\n]%*c", arr);/*当读入回车后结束字符串输入*/printf("%s\n", arr);fflush(stdin);return 0;
}
运行结果:
12313
1231
321.123445
321.120000
EW23ds32
EW23
awefdwe23
awefdwe
ASD12ds
ASD
AdseDsdswSSS123
AdseDsdswSSS
123243sdAdDSw
123243
2312dsd322
2312
dsfew23\<.?'"we23*&dfdewewfew=
dsfew23\<.?'"we23*&dfdewewfew
f*</12
f*</
few2323d.,23/][]2\23@#$%^&*()[]\
few2323d.,23/][]2\23@#$%^&*()[]\
Press any key to continue
程序分析:此处看上去挺复杂,其实很简短,说白了就是纸老虎。大家根据程序中的注释,以及运行结果进行操作,理解即可。程序是一种语言,既然是语言,只有经常的使用和练习才能更快的提高,所以大家要努力练习哟。
【例3.12】从键盘输入字符串,只获取字符串中的整数。比如输入“12ab34cd56”按行分别输出12,34,56,如运行结果所示。
解题思路:我们用scanf函数实现这样的功能,要求变量只接受数字,不接受其他字符即可。
程序编写:
#include <stdio.h>
int main()
{int n;while (scanf("%*[^0-9]") != EOF && scanf("%d", &n) != EOF){printf("%d\n", n);}return 0;
}
运行结果:
12ab34cd56
12
34
56
程序分析:程序第5行是一个while循环表示。while循环执行的顺序是:先执行while后面中括号中的数据,然后再执行大括号中的数据,执行完后再返回执行中括号中的数据,直到中括号中的数据为0或者NULL时,结束循环,顺序执行右花括号后面的语句。scanf("%*[^0-9]") 表示输入的数据不保存到任何变量中且遇到0-9中的任何一个或多个整数结束。另scanf("%d", &n)表示接受一个整数值。当输入12ab34cd56时,发现检测到又整数的数据,结束scanf("%*[^0-9]")的执行。然后执行scanf("%d", &n),即把12赋值给变量n,接着输出n等于12。可是为什么还会有34,56的输出呢?那是因为当你输入12ab34cd56后,这所有的数据都在缓存区中,你通过while循环依次的把所有的整数读入并且输出。如果你把while循环换成if判断,就会发现就只有12输出了,并不会再去读缓冲区中的其他数据。或者你在while循环中加入fflush(stdin);就会只输出第一次遇到的整数,而不再会输出该缓冲区之后遇到的整数。
同以上输入类似,那么如何只接受字符的输入呢?
【例3.13】输入一个字符串,只接受字母。
解题思路:与例3.11解题思路类似,不同的是此处要求只接受字母。同样,我们用scanf函数实现这样的功能,要求变量只接受字母,不接受其他字符即可。
程序编写:
#include <stdio.h>
int main()
{char ch;while (scanf("%*[^a-zA-Z]c") != EOF && scanf("%c", &ch) != EOF){printf("%c\n", ch);}return 0;
}
运行结果:
1H2ell23o,.W9orl65d';][
H
e
l
l
o
W
o
r
l
d
程序分析:程序第5行是一个while循环,while循环的使用大家参考例3.11即可。while循环后面的两个scanf函数表示只接受字符。如果不是字符就舍弃。比如在程序中输入“1H2ell23o,.W9orl65d';][”,结果输出为‘H’,‘e’,‘l’,‘l’,‘o’,‘w’,‘o’,‘r’,‘l’,‘d’。
3.4 puts和gets函数
前面讲解了一对输入输出函数:printf和scanf函数,这节我们将会讲解另一对输入输出函数——puts和gets函数。与printf和scanf函数不同,puts和gets函数只是从键盘接受字符串。而printf和scanf函数可以接受任何想要的数据类型。详细的puts和gets函数请大家接着往下学习。
3.4.1 puts和gets函数说明
puts函数用来向标准输出设备(一般是指输出到显示器)写字符串或字符数组或字符串指针。puts(s)函数的作用等效于printf(“%s\n”, s),需要注意:s是C语言风格的字符串,最后以’\0’结尾。
gets函数从标准输入设备(一般是指输出到显示器)读字符串函数。在缓冲区足够大且不会溢出的情况下,可以无限读取,不会判断上限,以回车结束读取。
但是gets函数函数在使用中如果不注意就会出现很多的问题。如果缓冲区较小,导致数据溢出,那么多出来的数据将被写入到堆栈中,这就覆盖了堆栈里原先的内容,破坏一个或多个与之不相关的变量的值。所以在真正的使用中我们多会使用fgets(stdin)或者使用scanf函数来代替gets函数的使用。
3.4.2 puts和gets函数格式
表3.8为 puts函数语法要点。
所需头文件 | #include<stdio.h> |
函数原型 | int puts(char *string); |
功能 | 输出字符串到流stdout中 |
函数返回值 | 成功:非负数 失败:EOF |
注意:
- puts函数只能输出字符串,不能输入数值或者进行格式转换。
- 可以把要输出的字符串直接写入puts()函数中,形如:puts(“IloveC.”)。
- 在输出字符串时会自动换行。
表3.9 为gets函数语法要点。
所需头文件 | #include <stdio.h> |
函数原型 | char * gets ( char * str ); |
功能 | 从stdin流中读取字符串,直至接受到换行符或EOF时停止 |
函数返回值 | 成功:返回与参数str相同的指针 遇到EOF或发生错误:返回NULL |
注意:
- gets函数读到\n(回车)时,停止读取,但是它并不把\n保存到字符串里去,而是在末尾添加‘\0’字符。
- 在遇到返回值为NULL的情况时,需要用ferror或feof函数检查是发生错误还是遇到EOF。
【例3.14】puts函数的基本使用。
解题思路:通过表3.8中有关puts函数的信息,进行编程。使用puts函数的头文件是stdio.h。puts函数功能输出一个字符串至输出流(一般是到屏幕上)。返回值暂时不用,且不管它。
编写程序:
1. #include <stdio.h>
2. int main()
3. {
4. char str[100] = "Hello My Lovely world!";
5. puts("Hello My Lovely world!");
6. puts(str);
7. return 0;
8. }
运行结果:
Hello My Lovely world!
Hello My Lovely world!
Press any key to continue
程序分析:程序第5行和第6行可以看出,puts函数既可以直接输出字符串,又可以直接输出字符数组。
【例3.15】gets函数的基本使用。
解题思路:gets函数与puts函数使用类似,我们参考表3.9和例3.14的解题思路,来使用我们的gets函数。
编写程序:
1. #include <stdio.h>
2. int main()
3. {
4. char str[100];
5. gets(str);
6. printf("%s\n", str);
7. puts(str);
8. return 0;
9. }
运行结果:
Hello C Program!
Hello C Program!
Hello C Program!
Press any key to continue
程序分析:第4行我们定义一个字符数组,用第5行的gets函数接受一个字符串。gets函数是以换行结束输入。输入的结果既可以printf函数输出,又可以用puts函数输出,请看程序第6~7行。
【例3.16】puts和gets函数的使用之用户登录。
解题思路:程序例3.15中就有puts函数和gets函数结合的简单使用。本程序以一个用户登录程序进行详细的使用说明。
编写程序:
1. #include <stdio.h>
2. #include <string.h>
3. int main()
4. {
5. char inputusername[24],inputpwd[24];//定义用户名和密码数组
6. //使用puts函数输出提示信息
7. puts("欢迎使用用户管理系统:");
8. puts("请输入用户名:");
9. //gets函数输入用户名,保存到inputusername中
10. gets(inputusername);
11. //使用strcmp函数进行比较,判断输入的用户名和正确的用户名是否一致
12. if (strcmp("username" , inputusername)!=0)
13. {
14. puts("用户名输入错误!");
15. return -1;
16. }
17. puts("请输入密码:");
18. gets(inputpwd);//gets函数输入密码,保存到inputpwd中
19. //使用strcmp函数进行比较,判断输入的密码和正确的密码是否一致
20. if (strcmp("password" , inputpwd)!=0)
21. {
22. puts("密码输入错误!");
23. return -1;
24. }
25. //如果用户名和密码一致,那就输出“登录成功”的提示信息
26. puts("登陆成功...");
27. return 0;
28. }
第一次运行结果:
欢迎使用用户管理系统:
请输入用户名:
username
请输入密码:
password
登陆成功...
Press any key to continue
第二次运行结果:
欢迎使用用户管理系统:
请输入用户名:
username
请输入密码:
pwd
密码输入错误!
Press any key to continue
第三次运行结果:
欢迎使用用户管理系统:
请输入用户名:
usrname
用户名输入错误!
Press any key to continue
程序分析:在程序讲解前我们首先了解strcmp函数的使用。strcmp函数传入两个参数。头文件为string.h。功能是比较两个传入的字符串的大小。字符串大小的比较是以ASCII码表上的顺序决定的。我们会在后面的章节对strcmp函数以及相应的字符串操作函数进行详细的介绍,大家此处只需要大概了解即可。接着我们做程序分析,在程序第1行为stdio.h,是puts和gets函数的头文件。第2行为string.h,是strcmp函数的头文件,第3行为main函数,为程序的入口。程序写在第4行和28行之间的花括号之间。程序第5行定义两个长度为24的字符串数组。第7~8行使用puts函数输出提示信息。第10行使用gets函数输入用户名。第12行if语句中是进行strcmp函数的判断,如果两个相等输出0,。如果第一个字符串大于(小于)第二个字符串输出大于(小于)0。如果输出结果不等于0,就表示两个字符串不相等。不行等就说明输入的结果不对,所以我们提示输入错误,然后结束程序的运行,返回-1表示程序出错。如果相等程序从第17行顺序执行。接下来程序的分析与上面相同。
3.5 putchar和getchar函数
上一节我们讲解了字符串的输入输出函数,那么这一节我们将会讲解字符的输入输出函数。这对函数就是putchar和getchar函数。这对函数与puts和gets函数有什么具体的区别呢?请听接着分解!!!哈哈。
3.5.1 putchar和getchar函数说明
C语言提供了两个单字符操作的函数,用于单字符的输入输出。
(1) putchar函数用于向标准输入输出设备输出一个字符。
一般的标准输出设备是指显示器。格式为putchar(c),其中c可以被单引号引起来,或者c是介于0~127之间的一个十进制整型数,c也可以是之前定义好的char类型字符变量。
- getchar函数用于从标准输入里读取下一个字符。
getchar函数是由宏实现的:#define getchar() getc(stdin)。当程序调用getchar()函数时,程序会等待用户输入字符,而用户输入的字符被存放在键盘的缓冲区中,直到用户输入回车为止,回车字符也会被放到缓冲区中。
3.5.2 putchar和getchar函数格式
表3.10与表3.11分别是putchar和getchar函数的语法要点。
所需头文件 | #include<stdio.h> |
函数原型 | void putchar(c); |
功能 | 输出单个字符 |
函数返回值 | void |
所需头文件 | #include<stdio.h> |
函数原型 | int getchar(void); |
功能 | 接受单个字符 |
函数返回值 | 成功:返回用户输入的ASCII码 失败:-1(即EOF) |
【例3.17】 putchar和getchar函数的使用。
解题思路:此处我们就直接使用两个函数,不在单独介绍。具体使用当然还是请大家观察表3.10和表3.11的对应语法要点。
编写程序:
1. #include <stdio.h>
2. int main()
3. {
4. int c;
5. while ((c=getchar())!='\n')//当输入回车时程序结束
6. {
7. if (EOF == c)//判断输入的结果是否正确
8. {
9. break;
10. }
11. putchar(c);//使用putchar函数输出输入的结果
12. }
13. getchar();//是程序暂停,按任意字符结束
14. return 0;
15. }
运行结果:
I love C program.
I love C program.
Press any key to continue
程序分析:程序第5行,会等到输入一个回车后,结束循环接受数据,然后把接受到的数据用putchar函数依次输出,因此程序会让你输入一个字符串“I love C program.”,按输入一个回车后,程序第11行才会通过putchar函数把所有的数据输出。第13行的getchar函数功能是让程序在该位置暂停,等待用户输入任意一个字符后,程序执行下一条语句。所以在程序输出“I love C program.”后,程序会处于等待接受状态,只有当你输入任意字符时程序才会结束。有人会对程序中的if语句产生疑问,为什么还需要判断c时候等于EOF呢?其实这个问题我们前面已经讲过,这是因为如果在程序中你输入Ctrl+z那么程序就会返回一个EOF值,就代表了程序结束。就是预防输入错误。
注意:
getchar()函数可以实现实现暂停,但是还有一种方法也是可以实现暂停的。该语句就是system(“pause”),不过需要头文件#include <stdlib.h>或#include <windows.h>。
3.6 getche与getch函数
上面几节讲解的都是成对的输入输出函数,那么本节我们将会讲解一对输入函数,因为这对输入函数在程序设计中使用的频率还是挺高的。比如如果我们要输入一个字符,要求程序立刻做出反应,而不是等到我们输入回车或者其他字符等才做出反应。那么getche和getch函数将会大放异彩。
可是这两个函数又有什么具体的区别呢?getche函数在我们输入字符后会在屏幕立刻显示我们输入的字符。而getch函数则不会显示字符。那么这两个函数是如何使用呢?我们接着往下学。
3.6.1 getche与getch函数说明
getche函数功能:输入后立即从控制台获取输入字符,不以回车结束,有回显,非缓冲。
getch函数功能:输入后立即从控制台获取一个字符,不以回车结束,无回显,非缓冲。是非标准C函数。
注:getche函数和getch函数都是接受字符的。
3.6.2 getche与getch函数格式
表3.12和表3.13分别是getche和getch函数的语法要点。
所需头文件 | #include<conio.h> |
函数原型 | int getche(void); |
功能 | 接受单个字符 |
函数返回值 | 成功:返回用户输入的ASCII码 失败:-1(即EOF) |
所需头文件 | #include<conio.h> |
函数原型 | int getch(void); |
功能 | 接受单个字符 |
函数返回值 | 成功:返回用户输入的ASCII码 失败:-1(即EOF) |
【例3.18】getche与getch函数的使用
解题思路:此处我们以一个简单的实例进行说明。废话不多说,程序见“真情”。
程序编写:
1. #include <stdio.h>
2. #include <conio.h>
3. int main()
4. {
5. char ch;
6. printf("使用getche()函数输入一个字符:");
7. ch = getche();
8. printf("\n输入的是'%c'\n", ch);
9. printf("使用getch()函数输入一个字符:");
10. ch = getch();
11. printf("\n输入的是'%c'\n", ch);
12. return 0;
13. }
运行结果:
使用getche()函数输入一个字符:f
输入的是'f'
使用getch()函数输入一个字符:
输入的是'd'
Press any key to continue
程序分析:运行程序时,第6行输出提示语句“使用getche()函数输入一个字符:”,然后等待输入数据。在程序第7行输入“f”后,不等按下回车,就会在控制台第2行输出字符‘f’,并且程序会顺序执行第8行,输出“输入的是'f'”。字符‘f’在控制台上显示出来的情况,这就表示有回显。顺序执行第9行输出“使用getch()函数输入一个字符:”,等待用户输入字符,而当输入字符‘d’后,发现控制台上并没有输出字符‘d’,直接输出了一句“输入的是'd'”,这就是无回显。
这篇关于第三章 初窥天机之顺序程序设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!