【谭浩强C程序设计精讲 7】数据的输入输出

3.5 数据的输入输出

3.5.1 输入输出举例

首先介绍一个含有输入函数 scanf 和输出函数 printf 的示例。

  • 功能要求:求 a x 2 + b x + c = 0 ax^2+bx+c=0 ax2+bx+c=0 方程的根。 a , b , c a,b,c a,b,c 由键盘输入。
  • 解题思路:首先要知道求方程式的根的方法。由数学知识已知:如果 b 2 − 4 a c ≥ 0 b^2-4ac\geq0 b24ac0,则一元二次方程有两个实根:
    x 1 = − b + b 2 − 4 a c 2 a , x 2 = − b − b 2 − 4 a c 2 a x_1=\frac{-b+\sqrt{b^2-4ac}}{2a}, x_2=\frac{-b-\sqrt{b^2-4ac}}{2a} x1=2ab+b24ac ,x2=2abb24ac
    可以将上面的分式分成两项:
    p = − b 2 a , q = b 2 − 4 a c 2 a p=\frac{-b}{2a},q=\frac{\sqrt{b^2-4ac}}{2a} p=2ab,q=2ab24ac


x 1 = p + q , x 2 = p − q x1=p+q,x2=p-q x1=p+q,x2=pq

有了以上公式,只要知道 a , b , c a,b,c a,b,c 的值,就能顺利地求出方程的两个根。

#include <stdio.h>
#include <math.h>   //程序中用到求平方根函数sqrt
int main(void)
{
  double a,b,c,disc,x1,x2,p,q;    //disc用来存放判别式(b*b-4*a*c)的值
  printf("请输入a,b,c的值:");
  scanf("%lf%lf%lf",&a,&b,&c);    //输入双精度型变量的值要用格式声明“%lf”,输入变量前面要加取地址符&
  disc=b*b-4*a*c;                 //求判别式的值
  while(disc<0)                   //判断输入的a,b,c值是否符合判别式大于等于0的要求
  {
      printf("输入的a,b,c的值不符合要求,请重新输入:");
      scanf("%lf%lf%lf",&a,&b,&c); 
      disc=b*b-4*a*c;             //重新求判别式的值
  }
  p=-b/(2.0*a);
  q=sqrt(disc)/(2.0*a);
  x1=p+q;x2=p-q;                 //求出方程的两个根
  printf("x1=%7.2f\nx2=%7.2f\n",x1,x2);   //“%7.2”表示整数部分占用7列,小数部分保留两位有效数字,且第三位小数按四舍五入。
  return 0;
}

测试结果1:
在这里插入图片描述

测试结果2:
在这里插入图片描述

3.5.2 有关数据输入输出的概念


  • 输入输出是以计算机主机为主体而言的。
  • 输出:从计算机向输出设备(如显示器、打印机等)输出数据称为输出。
  • 输入:从输入设备(如键盘、光盘、扫描仪等)向计算机输入数据称为输入。

  • C语言本身不提供输入输出语句,输入和输出操作是由C标准函数库中的函数来实现的。

  • C语言函数库中有一批标准的输入输出函数,它是以标准的输入输出设备(一般为终端设备)为输入输出对象的。其中有:

    函数名说明函数名说明函数名说明
    putchar输出字符printf格式输出puts输出字符串
    getchar输入字符scanf格式输入gets输入字符串

  • 要在程序文件的开头用预处理指令#include把有关头文件放在本程序中。
    如:
    #include <stdio.h>      //如果程序调用标准输入输出函数,必须包含该头文件
    #include <math.h>       //如果程序中用到标准数学库函数,必须包含该头文件
    

    需要说明的是:如果包含的头文件在C编译系统的子目录下使用#include <xxx.h>形式;如果包含的头文件在用户的当前目录(一般是用户存放源程序文件的子目录)中,则按#include "xxx.h"形式。


3.5.3 用 printf 函数输出数据

1. printf 的一般格式

printf 函数的一般形式:
printf(格式控制,输出表列)
例如:

printf("%d,%c\n",i,c);
  • “格式控制” 是用双撇号括起来的一个字符串,称为格式控制字符串,简称格式字符串。它包括两个信息:
    格式声明:由 “%”格式字符组成,如 %d、%f 等。

    它的作用是将输出的数据转换为指定的格式后输出。

    普通字符:需要在输出时原样输出的字符。如 逗号、空格、换行符或其他字符。

  • 输出表列:是程序需要输出的一些数据,可以是常量、变量或表达式


printf函数的一般形式也可以表示为:
printf(参数1, 参数2, 参数3, …, 参数n)

  • 参数1是格式控制字符串,参数2~参数n是需要输出的数据。
  • 执行 printf 时,参数2~参数n按参数1所指定的格式进行输出。
  • 参数1是必须有的,参数2~参数n是可选的。

2. 格式字符
表3.6 printf 函数中用到的格式字符
格式字符说明
d, i以带符号的十进制形式输出整数(正数不输出符号)
o以八进制无符号形式输出整数(不输出前导符0)
x, X以十六进制无符号形式输出整数(不输出前导符0x),用 x 则输出十六进制数的 a~f 时以小写形式输出,用 X 时,则以大写字母输出。
u以无符号十进制形式输出整数
c以字符形式输出,只输出一个字符
s输出字符串
f以小数形式输出单、双精度数,隐含输出6位小数
e, E以指数形式输出实数,用 e 时指数以 “e” 表示(如1.2e+02),用 E 时指数以 “E” 表示(如1.2E+02)
g, G选用 %f 或 %e 格式中输出宽度较短的一种格式,不输出无意义的0。用 G 时,若以指数形式输出,则指数以大写表示
表3.7 printf 函数中用到的格式附加字符
格式字符说明
l长整型数,可加在格式符 d、o、x、u前面
m(代表一个正整数)数据最小宽度
n(代表一个正整数)对实数,表示输出 n 位小数;对字符串,表示截取的字符个数
-(负号)输出的数字或字符在域内向左靠

以下将举例说明:
【例1】d格式符

printf("%5d\n%5d\n",12,-345);//%5d指定输出数据的位宽

运行结果:
在这里插入图片描述
说明:12前面有3个空格;-345前面有1个空格。

【例2】ld,lld格式符

#include <stdio.h>
int main()
{
    long i=123456;
    long long j=1234567890;
    printf("%ld\n%lld\n",i,j);//长整型用%ld打印,长长整型用%lld打印
    return 0;
}

运行结果:
在这里插入图片描述

【例3】c格式符

#include <stdio.h>
int main()
{
    char ch='a';
    printf("未指定位宽:%c\n",ch);
    printf("  指定位宽:%5c\n",ch);
    return 0;
}

运行结果:
在这里插入图片描述

说明:指定位宽的a前面有4个空格。

【例4】c格式符

#include <stdio.h>
int main()
{  
    short a=121;//定义一个值范围在0~127范围的整数,也可以用%c打印是字符y
    short b=377;//若值超过127,再用%c打印,则把最后一个字节的信息按字符形式输出
    printf("%c\n%c\n",a,b);//377的最后一个字节数值也是121
    return 0;
}

运行结果:
在这里插入图片描述

【例5】s格式符

printf("%s\n","CHINA");

运行结果:
在这里插入图片描述

【例6】f格式符
(1)基本型,%f,系统默认,整数部分全部输出,小数部分输出6位;
(2)指定数据宽度和小数位数,用 %m.nf,数据总的宽度为m,其中小数占列宽为n。

#include <stdio.h>
int main()
{  
    double a=1.0;
    printf("%f\n",a/3);//系统一般默认:整数部分全部输出,小数部分输出6位
    printf("%20.15f\n",a/3);//数据总的宽度为20,其中小数占列宽为15
    return 0;
}

在这里插入图片描述

说明:0前面有3个空格,为什么?可以在评论区讨论(标注:讨论1)。

【例7】float 型数据的有效位数

#include <stdio.h>
int main(void)
{
    float a;
    a=10000/3.0;
    printf("%f\n",a);
    return 0;
}

运行结果:
在这里插入图片描述

结果说明:因为float型数据只能保证6~7位有效数字,因此,虽然程序输出了6位小数,但从左边数第7位数字(即第3位小数)以后的数字并不保证是绝对正确的。

【例8】将例7中的a改成double

#include <stdio.h>
int main(void)
{
    double a;
    a=10000/3.0;
    printf("%f\n",a);
    return 0;
}

运行结果:
在这里插入图片描述

【例9】输出的数据向左对齐,用%-m.nf。

#include <stdio.h>
int main(void)
{
    double a;
    a=10000/3.0;
    printf("%-25.15f\n%25.15f\n",a,a);
    return 0;
}

运行结果:
在这里插入图片描述

【例10】e 格式符

#include <stdio.h>
int main(void)
{
    printf("%e\n",1234.567);
    printf("%13.2e\n",1234.567);
    return 0;
}

运行结果:
在这里插入图片描述

【例11】i 格式符。作用与d格式符相同,一般用d少用i。

#include <stdio.h>
int main(void)
{
    printf("%i\n",1234);  
    return 0;
}

运行结果:
在这里插入图片描述

【例12】o 格式符。以八进制整数形式输出。

#include <stdio.h>
int main(void)
{
    int a=-1;
    printf("%d\t%o\n",a,a);  
    return 0;
}

运行结果:
在这里插入图片描述

结果说明:-1在内存中是按补码形式存放4个字节的(1111 1111 1111 1111),因此%o按内存单元实际的二进制按3位一组(从右向左)构成八进制数形式。

【例13】x 格式符。十六进制整数形式输出。

#include <stdio.h>
int main(void)
{
    int a=-1;
    printf("%d\t%o\t%x\n",a,a,a);  
    return 0;
}

运行结果:
在这里插入图片描述

【例14】u 格式符。用来输出无符号型数据,以十进制形式输出。

#include <stdio.h>
int main(void)
{
    unsigned int a=10;
    int b=-10;
    printf("%d\t%u\n",a,a);  
    printf("%d\t%u\n",b,b);  
    return 0;
}

运行结果:
在这里插入图片描述

【例15】g 格式符。用来输出浮点数,系统自动选择f和e格式输出中长度短的那个。

#include <stdio.h>
int main(void)
{
    double a=12345678954321;
    printf("%f\n%e\n%g\n",a,a,a);   
    return 0;
}

运行结果:
在这里插入图片描述

【例16】普通字符原样输出,%字符输出。

#include <stdio.h>
int main(void)
{
    printf("输出%%\n");   
    return 0;
}

运行结果:
在这里插入图片描述

3.5.4 用 scanf 函数输入数据

1. scanf 函数的一般形式
  • scanf(格式控制,地址表列)
  • “格式控制”的含义同printf。
  • “地址表列”是由若干个地址组成的表列,可以是变量的地址,或字符串的首地址
2. scanf 函数中的格式声明
  • 以 % 开始,以一个格式字符结束,中间可以插入附加的字符。
    scanf("a=%f,b=%f,c=%f",&a,&b,&c);
    
表3.8 scanf 函数中用到的格式字符
格式字符说明
d, i输入有符号的十进制整数
u输入无符号的十进制整数
o输入无符号的八进制整数
x, X输入无符号的十六进制整数(大小写作用相同)
c输入单个字符
s输入字符串,将字符串送到一个字符数组中,在输入时以非空白字符开始,以第一个空白字符结束。字符串以串结束标志 ‘\0’ 作为其最后一个字符
f输入实数,可以用小数形式或指数形式输入
e,E,g,G与 f 作用相同,e 与 f、g 可以互相替换(大小写作用相同)
表3.9 scanf 函数中用到的格式附加字符
格式字符说明
l输入长整型数据(可用%ld,%lo,%lx,%lu)以及 double 型数据(%lf或%le)
h输入短整型数据(可用%hd,%ho,%hx)
域宽指定输入数据所占宽度(列数),域宽应为正数
*本输入项在读后不赋给相应的变量
3. 使用 scanf 函数时应注意的问题

(1)scanf 函数中的格式控制后面应当是变量地址,而不是变量名。

scanf("%f%f%f",a,b,c);      //错误
scanf("%f%f%f",&a,&b,&c);   //正确

(2)如果在格式控制字符串中除了格式声明以外,还有其他字符,则在输入数据时在对应的位置上输入与这些字符相同的字符。

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

运行结果:
在这里插入图片描述

结果说明:在输入时必须按照原字符原样输入,比如控制字符串中有逗号,如果不输入逗号改成空格是错误的,输入结束后回车。

(3)在用 “%c” 格式声明输入字符时,空格字符和“转义字符”中的字符都作为有效字符输入。

#include <stdio.h>
int main()
{  
    char c1,c2,c3;
    scanf("%c%c%c",&c1,&c2,&c3);
    printf("%c\t%c\t%c\n",c1,c2,c3);
    return 0;
}

测试结果1:
在这里插入图片描述

测试结果2:
在这里插入图片描述

(4)在输入数值数据时,如输入空格、回车、Tab键或遇非法字符(不属于数值的字符)认为该数据结束。

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

运行结果:
在这里插入图片描述

结果说明:第一个要求输入的是整型数值,输入1234后面输入了一个非数值字符a,则第一个整型变量值就为1234了。因为第2个要求输入一个字符,所以输入的字符a即为第2个字符型变量的值。第3个要求输入浮点型数据,第一个数字开始到非数值结束,因为遇到字母o(字母o实际上是要输入数字0的,但是输入错误了,结果也错了)时结束。

3.5.5 字符输入输出函数

1. 用 putchar 函数输出一个字符
  • putchar 函数的一般输出格式:
    putchar©
    举例:

    #include <stdio.h>
    int main()
    {  
        char a='B',b='O',c='Y';  //定义三个字符变量并初始化
        int a1=66,b1=79,c1=89;  //定义三个整型变量并初始化BOY三个字符的ASCII码值
        putchar(a);
        putchar(b);
        putchar(c);
        putchar('\n');
        putchar(a1);
        putchar(b1);
        putchar(c1);
        putchar('\n');
    }
    

    运行结果:
    在这里插入图片描述

2. 用 getchar 函数输入一个字符
  • getchar 函数的一般格式:
    getchar()

  • getchar函数没有参数,它的作用是从计算机终端输入一个字符。

  • 示例1:

      #include <stdio.h>
      int main()
      {  
          char a,b,c;     //定义三个字符变量
          
          a = getchar();     //从键盘输入一个字符,送入字符变量a
          b = getchar();     //从键盘输入一个字符,送入字符变量b
          c = getchar();     //从键盘输入一个字符,送入字符变量c
          putchar(a);
          putchar(b);
          putchar(c);
          putchar('\n');
      }
    

    (1)若键盘输入三个字符boy,中间无任何字符,然后回车,输出打印boy。
    测试结果1:
    在这里插入图片描述

    (2)若键盘每输入一个字符,按一次enter回车键,输出是什么样的?
    测试结果2:
    在这里插入图片描述

  • 示例2:输入的字符不传送给变量直接输出boy

    #include <stdio.h>
    int main()
    {  
        putchar(getchar());
        putchar(getchar());
        putchar(getchar());
        putchar('\n');
    }
    

    测试结果:
    在这里插入图片描述

  • 示例3:从键盘上输入任意一个大写字母,在显示屏上显示相应的小写字母。

     #include <stdio.h>
     int main()
     {  
         char c1,c2;
         c1 = getchar();     //从键盘上输入一个大写字母,送给字符变量c1
         c2 = c1+32;         //求对应小写字母的ASCII代码,放在字符变量c2中
         //使用puchar输出
         putchar(c2);
         putchar('\n');
         //使用printf输出
         printf("大写字母:%c\n小写字母:%c\n",c1,c2);
     }
    

    运行结果:
    在这里插入图片描述


    本节完

  • 48
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MJY二进制

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值