带你读《C语言程序设计教程 第4版》之三:数据的输入和输出

点击查看第一章
点击查看第二章
第3章

数据的输入和输出

本章主要介绍C语言中数据输入和输出的方法。
主机向外部输出设备(包括显示器、打印机等)输出数据称为数据的输出,反之,使用外部输入设备(键盘、扫描仪等)向计算机主机输入数据称为数据的输入。C语言本身并没有提供专门的数据输入/输出语句,而是通过调用系统提供的标准输入/输出库函数来实现数据的输入和输出。
在使用标准的输入/输出库函数时,使用编译预处理命令“#include ”将stdio.h头文件写在程序的开头,该文件包含了与输入/输出相关的变量定义、宏定义和函数声明。

3.1数据的输出

3.1.1格式输出函数printf

1. 函数的基本功能
一般形式:printf(格式控制字符串,输出表列)
功能:按指定格式,向终端(或系统隐含指定的输出设备)输出若干个任意类型的数据。
2. 函数的使用说明
printf函数需要提供两类参数,一类是格式控制字符串,另一类是输出表列。
格式控制字符串用来指出在输出设备(以后均设定输出设备是屏幕)上输出的格式,该字符串指出输出后显示的样式。格式控制字符串也称转换控制字符串,它包括格式说明符和普通字符两种信息:
1)格式说明符:由“%”和格式符组成,如%d、%f等。它的作用是将输出表列的数据转换为指定的格式输出。格式说明符总是由“%”字符开始。
2)普通字符:是指格式控制字符串中除格式说明符外的其他字符,其中包括转义字符,这是一类需要原样输出的字符。
“输出表列”是需要输出的一系列数据,可以是常量、变量和表达式。
“格式控制字符串”中格式说明符的个数和输出表列的项数相等,顺序为从左到右依次对应。
printf函数按格式控制字符串的格式输出信息,输出过程是从左到右逐个考察函数中格式控制字符串的每个字符。如果该字符是普通字符,就将它原封不动地输出到显示器上;如果该字符是格式说明符,就在输出表列中从左到右找到对应的数据项,按格式说明符指定的类型和格式输出。
在使用格式说明符时特别要注意,除了在可显示的字符范围内,整型和字符型格式说明符可以互换,%f格式说明符可以用来输出单精度实数和双单精度实数外,格式说明符的类型必须与其对应的输出表列中数据的类型一致。
【例3-1】阅读程序。

#include <stdio.h>
int main( )
{
  int a=3,b;
  printf("a=%d,b=%d\n",a,b=4);
  return 0;
}

其中
"a=%d,b=%d" 格式控制字符串
a,b=4 输出表列
%d 格式说明符
"a=" ",""b=" 普通字符
运行结果:
a=3,b=4
3. 格式说明符
在C语言中,格式输入和输出函数对不同类型的数据必须采用不同的格式说明符。
一般形式:
%-或0.[l]格式符
说明:
1)方括号中的内容是可选项。数据的宽度表示数据输出到屏幕上时所占的水平位置的长度,与数据实际字符的个数一致,例如3.14的宽度为4。
2)-(负号):表示当实际数据的宽度小于显示宽度时,数据左对齐,数据右边用空格填充。0表示当实际数据的宽度小于显示宽度时,数据右对齐,数据左边空格用0填充。
3)m:表示占用数据的宽度,如果实际数据的宽度大于m,按实际宽度输出。如果实际数据的宽度小于m,数据右对齐,数据左边用空格填充。
4)n:表示指定输出的数据中有n位小数,或者表示取字符串中左端n个字符输出。如果不指定该项,一般系统默认输出6位小数。
5)m.n:表示指定输出的数据共占m列,其中有n位小数,舍去的部分系统自动四舍五入。如果输出的是字符串,表示取字符串中左端n个字符输出。
6)l:用于长整型或双精度型的数据。
7)用%%表示字符%。
注意 本章中规定用字符“□”表示空格,以便读者能清楚地分辨出显示的空格个数。
格式符的种类很多,如果输出表列的每项数据的类型不同,格式说明符中需要选择不同的格式符与之对应,printf函数中使用的格式符参考表3-1。

表3-1printf函数中使用的格式符

带你读《C语言程序设计教程 第4版》之三:数据的输入和输出
下面按照输出的数据类型的不同,详细介绍各种格式符在程序中的使用方法。
(1)整型数据
一般形式:%-或0[l]格式符
格式符与对应的输出形式如表3-1所示。如果不指定数据宽度和对齐方式,例如%d,系统自动按整型全部输出。
说明:
1)d格式符(或i格式符),用来输出十进制整数。有以下几种:

  • %d:按整型数据输出。
  • %ld:输出长整型数据。但在Visual C++系统中,%d和%ld没有区别。

2)o格式符,以八进制数形式输出正整数或无符号整数。
o格式符是将内存单元中各位的值(0或1)按八进制形式输出,因此输出的数值不带符号。例如:
printf("%d, %o",8,8);
结果是:
8, 10
3)x格式符,以十六进制数形式输出正整数或无符号整数,同样不会出现负的十六进制数。它有两种写法,即%x和 %X,分别对应十六进制数中字母的大小写形式。例如:
printf("%d, %x, %X",15,15,15);
结果是:
15, f, F
4)u格式符,以十进制形式输出unsigned型数据,即无符号整数。
(2)实型数据
一般形式:
%-或0.类型符
实型数据的输出有以下三种格式符:
1)f格式符,以小数形式输出实数。
一般形式:
%-或0.f
如果不指定数据宽度和对齐方式,例如%f,系统将自动指定,使整数部分全部如数输出,并输出6位小数。
2)e格式符,以指数形式(科学记数法)输出实数。
一般形式:
%-或0.e 或 %-.E
对应的输出形式是:
(数字部分)e(指数部分)或(数字部分E 指数部分)
数值按标准化指数形式输出,即小数点前有且仅有一位非零数字。
【例3-2】阅读程序。

#include <stdio.h>
int main( )
{
  float x=12.345f;
  double y=2.346;
  printf("x1=%f,x2=%6.2f,x3=%-6.2f,x4=%.2f\n",x,x,x,x);
  printf("x5=%e,x6=%10.2e,x7=%-10.2e,x8=%.2e\n",x,x,x,x);
  printf("y1=%f,y2=%6.2f,y3=%-6.2f,y4=%.2f\n",y,y,y,y);
  printf("y1=%lf,y2=%6.2lf,y3=%-6.2lf,y4=%.2lf\n",y,y,y,y);
  return 0;
}

运行结果:
x1=12.345000,x2=□12.35,x3=12.35□,x4=12.35
x5=1.234500e+001,x6=□1.23e+001,x7=1.23e+001□,x8=1.23e+001
y1=2.346000,y2=□□2.35,y3=2.35□□,y4=2.35
y1=2.346000,y2=□□2.35,y3=2.35□□,y4=2.35
3)g格式符,用来输出实数,它根据数值的大小,自动选f格式或e格式中输出时占宽度较小的一种。
(3)字符型数据
字符型数据的输出有以下两种格式符:
1)c格式符,用来输出一个字符。
一般形式:%c
一个整数,只要它的值在33~126范围内,就可以用字符形式输出,在输出前,将该整数转换成相应的ASCII字符;反之,一个字符数据,只要它的ASCII码值在33~126范围内,就可以用整数形式输出。
【例3-3】阅读程序。

#include <stdio.h>
int main( )
{
  char ch='a'; int i=97;
  printf("%c,%d\n",ch,ch);
  printf("%c,%d\n",i,i);
  return 0;
}

运行结果:
a,97
a,97
2)s 格式符,用来输出一个字符串。
一般形式:%-或0.s
如果不指定字符宽度和对齐方式,例如%s,系统将自动指定,使整个字符串全部输出。
【例3-4】阅读程序。

#include <stdio.h>
int main( )
{
  printf("s1=%05.2s,s2=%-5.2s,s3=%.2s,s4=%3s,s5=%s\n",
         "abcd","abcd","abcd","abcd","abcd");
  return 0;
}

运行结果:
s1=000ab,s2=ab□□□,s3=ab,s4=abcd,s5=abcd
3.1.2字符输出函数putchar
一般形式:int putchar(char ch)
功能:向终端(或系统隐含指定的输出设备)输出一个字符。
返回值:成功时返回输出字符的ASCII码,否则返回-1。
说明
1)可以输出转义字符。
2)可以将字符变量定义成int 型或char型。
【例3-5】阅读程序。

#include <stdio.h>
int main( )
{
  char c1='A',  c2=66 ;
  int  c3='\103', c4 ;
  c4=c3+1;
  putchar(c1); putchar(c2);
  putchar('\n');
  putchar(c3); putchar(c4);
  putchar('\n');
  return 0;
}

运行结果;
AB
CD

3.2数据的输入

3.2.1格式输入函数scanf

1. 函数的基本功能
一般形式:scanf(格式控制字符串, 地址表列)
功能:按指定格式,用键盘(或系统隐含指定的其他输入设备)输入若干个任意类型的数据。
说明:
1)scanf函数需要提供两类参数,一类是格式控制字符串,另一类是地址表列。
2) “格式控制字符串”用来指出在输入设备(以后均设定输入设备是键盘)上输入的格式,包括格式说明符和普通字符两种信息,格式说明符的基本含义与printf函数中的“格式说明符”相同。
3)“地址表列”是由若干个地址组成的表列,可以是变量的地址或字符串的首地址。
格式控制字符串中格式说明符的个数和地址表列的项数相等,顺序为从左到右依次对应。scanf函数按格式控制字符串的格式输入信息,输入过程是函数从左到右逐个考察格式控制字符串的每个字符。如果该字符是普通字符,则必须按照该字符的内容原封不动地用键盘输入到显示器上;如果该字符是格式说明符,则按格式说明符指定的类型和格式输入一个数字或字符。
scanf函数中使用的格式符参考表3-2。

表3-2scanf函数中使用的格式符

带你读《C语言程序设计教程 第4版》之三:数据的输入和输出
2. 函数的使用说明
1)键盘输入时如何与格式控制字符串对应, 从而使变量获得准确数据?这个问题可分为以下4种情况:
格式控制字符串无任何普通字符。在程序运行中需要输入非字符类数据时,两个数据之间以一个或多个空格间隔,也可以按回车键、制表键(Tab)间隔。例如:

int a,b,c;
scanf("%d%d%d", &a,&b,&c);

  其中,“%d%d%d”表示按十进制整数形式输入数据。对应的键盘输入为:
34<空格>5<回车>
  或
3<回车>4<回车>5<回车>
  或
3<空格>4<空格>5<回车>
注意 在本书中,<回车>表示Enter键,<空格>表示空格键,表示Tab键。
格式控制字符串中存在普通字符。格式控制字符串中的普通字符一般用来分隔输入的数据项。在程序运行中需要输入数据时,对于“普通字符”,必须按照该字符的内容原封不动地用键盘输入到显示器上,如果输入的内容和格式字符串的内容不一致,则scanf 函数立即结束。
【例3-6】阅读程序。

#include <stdio.h>
int main( )
{
  int a=0,b=0,c=0;
  printf("Input a=,b=,c=\n");
  scanf("a=%d,b=%d,c=%d", &a,&b,&c);
  printf("a=%d,b=%d,c=%d",a,b,c);
  return 0;
}

程序运行情况:

Input a=,b=,c=
a=1,b=2,c=3 <回车>
a=1,b=2,c=3

上例中,如果键盘输入内容是:
a=1,a=2,c=3<回车>
运行结果:
a=1,b=0,c=0
在输入变量b值之前,出现错误,把"b="误写为"a=",导致scanf 函数立即结束,因此,变量b和变量c仍然保持原来的值。
可以指定输入数据所占列数,系统将根据指定列数自动截取所需数据。例如:

scanf("%3d%3d",&a,&b);

  输入:
123456789<回车>
printf("a=%d,b=%d",a,b);
  输出:
a=123,b=456
数字型数据和字符型数据混合输入。
【例3-7】阅读程序。

#include <stdio.h>
int main( )
{
  int a,b,c,d;
  scanf("%d%c%c%c",&a,&b,&c,&d);
  printf("a=%d,b=%c,c=%c,d=%c\n",a,b,c,d);
  return 0;
}

输入:
123abc<回车>
运行结果:
a=123,b=a,c=b,d=c
如果输入123<回车>abc<回车>,结果为a=123,b=,c=a,d=b,系统将<回车>作为有效字符赋给字符变量b,依次向后推移,将'a'赋给字符变量c,将'b'赋给字符变量d,从而导致错误的结果。
2)输入 double型数据时,必须使用格式说明符%lf或%le,不能直接使用%f或%e。例如:

double x,y;
scanf("%lf%lf",&x,&y);

3)输入数据时不能规定精度。例如,下面的输入语句是非法的:

float x;
scanf("%6.2f",&x);

4)对unsigned型数据,可以用%u、%d或%o、%x格式输入。
5)%后的“*”为附加说明符,用来表示跳过相应的数据。例如:

scanf("%2d,%*3d,%2d",&a,&b);
printf("a=%d,b=%d\n",a,b);

输入:
12,345,67<回车>
运行结果:
a=12,b=67
系统自动跳过了345,使得b=67。

3.2.2字符输入函数getchar

一般形式:int getchar()
返回值:成功时返回输入字符的ASCII码,否则返回-1。
功能:从键盘(或系统隐含指定的输入设备)接收一个字符。
说明:
1)只能接收一个字符。
2)可以将获得的字符赋给int 型或char型的变量。
3)可以用来接收键盘输入的不必要的回车或空格,或使运行的程序暂停。
【例3-8】阅读程序。

#include <stdio.h>
int main( )
{
  char c1;
  int  c2;
  printf("\nInput three characters:\n");         //输入提示
  c1=getchar();                               //将键盘输入的字符赋值给变量c1
  putchar(c1);                               //输出
  c2=getchar();
  putchar(c2);
  putchar(getchar());                 //将键盘输入的字符直接输出
  putchar('\n');
  return 0;
}

程序运行情况:
Input three characters:
HEI<回车>
HEI
【例3-9】程序用getchar()接收键盘输入的不必要的回车或空格。

#include <stdio.h>
int main( )
{
  int a;
  char b;
  printf("Input a,b:\n ");
  scanf("%d",&a);
  getchar();               //接收上条语句回车避免将其作为有效字符输入给字符变量b
  scanf("%c",&b);
  printf("a=%d,b=%c\n",a,b);
  return 0;
}

程序运行情况:
Input a.b:
12<回车>
K<回车>
a=12,b=k;
【例3-10】程序用getchar()实现暂停。

#include <stdio.h>
int main( )
{
  printf("Step 1:\n");
  printf("Step 2:\n");
  printf("Step 3:\n");
  printf("按Enter键继续......");
  getchar();
  printf("Step 4:\n");
  printf("Step 5:\n");
  printf("Step 6:\n");
  return 0;
}

程序运行情况:
Step 1:
Step 2:;
Step 3:
按Enter键继续...... <回车>
Step 4:
Step 5:;
Step 6:

3.3应用举例

【例3-11】输入直角三角形的两个直角边的边长,求斜边的长度和三角形的面积。

#include <math.h>                  //包含一个数学函数库头文件
#include <stdio.h>
int main( )
{
  double a,b,c,area;
  printf("Input a,b\n");          //输入提示,a,b为两个直角边长度
  scanf("%lf%lf",&a,&b);           //输入a,b值
  printf("a=%f, b=%f\n",a,b);       //输出a,b值验证一下
  c=sqrt(a*a+b*b);                 //sqrt是数学平方根函数
  area=1./2*a*b;
  printf("c=%-7.2f",c);
  printf("area=%-7.2f\n",area);
  return 0;
}

程序运行情况:
Input a,b
3□4<回车>
a=3.000000,b=4.000000
c=5.00□□□area=6.00
【例3-12】根据下面的输出结果编写程序,要求用scanf函数输入。
ch='A',ASCII=65
i=1□□j=2
x=12.34□□□y=56.78
编写程序如下:

#include <stdio.h>
int main( )
{
  char c;
  int i,j;
  float x,y;
  printf("Input c,i,j,x,y\n");                  //输入提示
  scanf("%c,%d,%d,%f,%f",&c,&i,&j,&x,&y);    //键盘交互输入
  printf("ch=\'%c\', ASCII =%d\n",c,c);         //输出c值并换行
  printf("i=%-3dj=%d\n",i,j);                 //输出i,j值并换行
  printf("x=%-8.2fy=%.2f\n",x,y);             //输出x,y值
  return 0;
}

输入:
A,1,2,12.34,56.78<回车>
运行结果与题目要求一致。由于输入格式中有逗号,因此运行时输入数据也要加上逗号。

小结

C语言本身并没有提供专门的数据输入/输出语句,而是通过调用系统提供的标准输入/输出库函数来实现数据的输入和输出。将stdio.h头文件写在程序的开头,该文件包含了与输入/输出相关的变量定义、宏定义和函数声明。
C语言中有关输入和输出函数的规定比较烦琐,建议读者通过编程实践来逐步掌握。对于数据的输入,初学者经常出现由于没有正确地使用scanf函数,导致程序中变量的数据不正确,即使程序的其他部分没有错误,也可能造成最后的结果不正确。因此,建议初学者在scanf函数前加一个printf函数,输出一个有关变量输入内容的提示。在scanf函数被执行后再加一个printf函数,输出各个变量的值,从而保证输入内容的正确无误。
数据的输出也很重要,要求输出表列的数据项与格式说明符的个数相同,依次对应,最重要的是类型匹配。否则由于系统不给出错误提示,即使前面程序的算法没有错误,计算结果正确,也不能看到正确的输出结果,可谓“功亏一篑”。

习题

一、选择题

以下各题在给定的四个答案中选择一个正确的答案。

  1. 已有定义“char s1,s2;”,下面正确的语句是(  )。
     A. scanf ("%s%c", s1,s2); B. scanf ("%s%c", s1,&s2);

 C. scanf ("%c%c", &s1,&s2); D. scanf ("%c%c",s1,s2);

  1. 为下面的程序输入数据,使得i=10,k='a' ,j=15,正确的键盘输入方法是(  )。
#include <stdio.h>
int main( )
{
   int  i,j;  char k;
   scanf("%d%c%d",&i,&k,&j);
   printf("i=%d,k='%c',j=%d\n",i,k,j);
   return 0;
}

 A. 10,a,15<回车> B. 10<回车>a<回车>15<回车>
 C. 10'a'15<回车> D. 10a15<回车>

  1. 运行下面的程序,正确的输出结果是(  )。
#include <stdio.h>
int main( )
{
  double  x=68.7563, y= -789.127;
  printf ("%f, %10.2f\n", x,y);
  return 0;
}

 A. 68.756300, □□□-789.12 B. 68.756300, □□□-789.13
 C. 68.75, □□□-789.13 D. 68.75, -789.12

  1. 已知“float x=2.23,y=4.35;”,根据下面的输出结果,正确的程序段是(  )。
    x=2.230000,y=4.350000

y+x=6.58,y-x=2.12
A. printf("x=%8.2f,y=%8.2f",x,y); B. printf("x=%8.6f,y=%8.6fn",x,y);
printf("y+x=%4.2f,y-x=%4.2fn",y+x,y-x); printf("y+x=%4.2f,y-x=%4.2fn",y+x,y-x);
C. printf("x=%7.2f,y=%7.2fn",x,y); D. printf("x=%f,y=%fn",&x,&y);
printf("y+x=%3.2f,y=%3.2fn",y+x,y-x);   printf("y+x=%f,y=%fn",y+x,y-x);

二、完善程序题

 以下各题在每题给定的A和B两个空中填入正确内容,使程序完整。

  1. 用scanf函数输入数据,使得x=1.23, y=67.1234。
#include <math.h>
#include <stdio.h>
int main( )
{
   double  x,y,z;
   scanf("  A  ",   B  );
   z=2*x+y/sin(3.1415/4);
   printf("z=%6.2f",z);
   return 0;
}
#include  <  A  >
int main( )
{
  char  str;
    B  =getchar();
  putchar(str);
  return 0;
}
  1. 根据下面的输出结果,完善程序。
    s1=C,ASCII is 67

x=655.35,y=765.43

#include <stdio.h>
int main( )
{
      A  x=655.3524,y=765.4271;

    char s1='C';
    printf(  B  ,  s1,s1,x,y);
    return 0;
}
  1. 用scanf函数输入数据,使得程序运行结果为a=2,b='x',c='z'。
#include <stdio.h>
int main( )
{
  int   a, b;
  scanf("%d%c",  A  );
  printf("  B  ",a,b,b+2);
  return 0;
}

三、阅读程序题

 写出以下程序的运行结果。
1.

#include <stdio.h>
int main( )
{
  int i=19,j=12;
  double  x=3.1415,y=153.125;
  char ch='*';
  printf("(1)\ti=%d\tj=%d\n",i,j);
  printf("(2)\tx=%.2f\ty=%.2e\n",x,y);
  printf("(3)\t%c\t%c\t%c\n",ch,ch,ch);
  printf("(4)\t%s\t%.3s\t%.2s\n","Hello","Hello","Hello");
  return 0;
}

 运行结果:          。
2.

#include <stdio.h>
int main( )
{
  char str=65;
  printf("str=%c,ASCII=%d",str,str);
  printf("\nstr=%c,ASCII=%d\n",str+1,str+1);
  return 0;
}

 运行结果:          。

四、程序改错题

 指出下列程序中两处错误的语句,并改正。

#include <stdio.h>
int main( )
{
   float  x,y,z;
   scanf("%5.2f, %5.2f" ,&x,&y);
   z=x+y;
   printf("z=%5.2f\n",&z);
   return 0;
}

2.

#include <stdio.h>
int main( )
{
   short int x=7654123;
   x*=10;
   printf("x=%d\n,x);
   return 0;
}

3.

#include <stdio.h>
int main( )
{
  float  c1=67;
  char  c2;
  c2=c1+5;
  printf("c1=%c,c2=%c\n",c1,c2);
  printf("c1=%d,c2=%d\n",&c1,&c2);
  return 0;
}

五、编写程序题

 已知“char ch='b'; int i=3, j=5; float x=22.354,y=435.6789;”,根据下面的输出结果编写程序。
ch='b',ASCII=98
i=3□□□□□j=5
x=22.35□y=435.68

上一篇:敲黑板:“API经济”的四个关键词


下一篇:如何在Linux上添加或编辑文件系统的卷标