欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C语言基础10:复杂数据的输入输出

C语言基础10:复杂数据的输入输出

2025/2/11 11:02:03 来源:https://blog.csdn.net/m0_74147998/article/details/145557144  浏览:    关键词:C语言基础10:复杂数据的输入输出
复杂的输入输出

按指定格式输出数据的宽度、小数位数、上下行数据按小数点对齐、用八进制、十六进制输出等。

输出数据格式的控制
整型格式说明符
  • 十进制形式(0~9)

    说明符说明数据类型
    %d和%md用于基本整型int
    %ld和%mld用于长整型long
    %u和%mu用于无符号基本整型unsigned int
    %lu和%mlu用于无符号长整型unsigned long
  • 八进制(0~7)

    说明符说明数据类型
    %0和%mo用于基本整型int
    %lo和%mlo用于长整型long
  • 十六进制形式(0~F)

    说明符说明数据类型
    %x和%mx用于基本整型int
    %lx和%mlx用于长整型long

    m表示输出整型数据所占总宽度(即列数),其中:

    ①当实际数据的位数不到m位时,数据前面将用空格填满;

    ②若实际数据的位数大于等于m位时,则以数据的实际位数为准进行输出;

    一个int型整数也可以用%u输出,反之一个unsigned型整数也可以用%d、%o、%x格式输出。按相互赋值的规则处理。

    举例:

    /*************************************************************************
    > File Name:demo03.c
    > Author:zk
    > Description:
    > Created Time: 2025年02月10日 星期一 15时37分14秒
    ************************************************************************/#include <stdio.h>int main(int argc,char *argv[])
    {printf("%d\n",12);// 实际只占2列,12printf("%6d\n",12);// m是正数,实际占了6列,前面不足的使用空格填充,♦♦♦♦12printf("%-6d\n",12);// m是负数,实际占了6列,后面不足的使用空格填充,12♦♦♦♦printf("%6d\n",12345678); // 如果实际的数据列宽超过了规定的列宽,列宽失效,按照实际显示,12345678return 0;
    }
字符型格式说明
  • 字符型

    说明符说明举例
    %c或者%mc输出的字符占m列printf(“%3c\n”,‘a’);
  • 字符串型

    在C语言中,是支持字符串常量的,但是不支持字符串变量。

    说明符说明
    %ms输出的字符串占m列。若串长>=m,全部输出;反之在串前补空格(m为补空格)
    举例:printf(“%6s\n”,hello); // ♦hello
    %-ms输出的字符串占m列。若串长>=m,全部输出;反之在串后补空格(m为负往后补空格)
    举例:printf(“%-6s\n”,hello); // hello♦
    %m.ns输出的字符串占m列。只取字符串前n个字符,不足部分串前补空格。
    举例:printf(“%6.2s\n”,“hello”); // ♦♦♦♦he
    %-m.ns输出的字符串占m列。只取字符串前n个字符,不足部分串后补空格。
    举例:printf(“%-6.2s\n”,“hello”); // he♦♦♦♦

    注意:因为空格本身不是很好区分,笔记中使用♦代替空格显示

    一个整数,只要其值在0~255范围内,也可以用%c格式按其字符形式输出。这里0~127对应ASCII。在输出前,系统会自动将整数作为ASCII码转换成相应的字符;反之,一个字符也可以输出成一个整数。

案例:

  • 要求:字符串输出

  • 代码:

    #include <stdio.h>int main()
    {printf("%3s,%7.2s,%-5.3s,%.4s\n","CHINA","CHINA","CHINA","CHINA");return 0;
    }
    
  • 运行结果:

CHINA,♦♦♦♦♦CH,CHI♦♦,CHIN

浮点型格式说明符

浮点型格式分为三种形式:

  • 十进制形式:%m.nf或者%-m.nf
  • 指数形式:%m.ne或者%-mne
  • %g或者%G形式:根据数值的大小,自动选择%f或者%e中宽度较短的一种格式,不输出无意义的0

解释:

​ 在输出浮点型数据时,格式说明符中的m表示整个数据所占的列宽,n表示小数点后面所占的位数(保留的小数位)如果在小数点后取n位后,所规定的数据宽度m不够输出数据前面的整数部分(包括小数点),则按实际的位数进行输出。

在C语言中,用于输出单精度浮点型与双精度浮点型数据格式说明符一样的。

案例:

  • 要求输出浮点型数时,指定小数位

  • 代码:

    #include <stdio.h>int main()
    {float f = 123.456;printf("%8.2f,%-8.2f,%8.6f,%8.2e,%g\n",f,f,f,f,f);return 0;
    }
    
  • 运行结果:

♦♦123.46,123.46♦♦,123.456001,1.23e+02,123.456 123.456 = = 1.23456 ∗ 1 0 2 = = 1.23456 e 2 123.456 == 1.23456*10^2==1.23456e^2 123.456==1.23456102==1.23456e2

案例:

  • 要求:求3个圆的周长,输出结果时上下按小数点对齐,取两位小数

  • 代码:

    #include <stdio.h>
    #define PI 3.1415926
    void main ( )
    {double r1=1.53,r2=21.83,r3=123.71,s1,s2,s3;s1=2.0*PI*r1;s2=2.0*PI*r2;s3=2.0*PI*r3;printf("s1=%10.2f\ns2=%10.2f\ns3=%10.2f\n",s1,s2,s3)return 0;
    }
    
  • 运行结果:

在这里插入图片描述

案例:

  • 要求:设有如下C程序

  • 代码:

    #include "stdio.h"
    main()
    {double x=34.567;printf("x=%f\n",x);// 34.567000printf("x=%d\n",x);// 27263,这种写法错误,自动类型转换异常printf("x=%d\n",(int)x);// 34
    }
    
  • 这个程序的实际运行结果为

    x=34.567000

    x=27263

    x=34

  • 说明:

    显然,这个程序中的第二个格式输出语句输出的结果是错误的,这是因为在第二个格式输出语句中,格式说明符%d是基本整型格式说明符,而输出项目是双精度型的数据,它们是不匹配的。

输入数据格式的控制
整型格式说明符
  • 十进制形式(0~9)

    说明符说明数据类型
    %d用于基本整型int
    %ld用于长整型long
    %u用于无符号基本整型unsigned
    %lu用于无符号长整型unsigned long
  • 八进制(0~7)

    说明符说明数据类型
    %0用于基本整型int
    %lo用于长整型long
  • 十六进制形式(0~F)

    说明符说明数据类型
    %x用于基本整型int
    %lx用于长整型long

可见:
① 用于输入与输出整型数据的格式说明符是完全一致的。
② 与输出情形一样,对于八进制与十六进制的输入格式,主要用于输入无符号的整型数
据。

浮点型格式说明符
  • 单精度浮点型:%f或者%e
  • 双精度浮点型:%lf

可见:

①与输出不同,输入时无论是单精度还是双精度浮点型,都不能用m.n来指定输出的宽度和小数点后的位数。

②可以指定输入数据所占的列数,系统自动按他截取所需数据,如:

scanf("%3d%3d",&a,&b);当输入1234567时,a得到123,b得到456,多余的7无用。

③若在%后有一个*和一个数字,表示跳过他指定的列数,如:

scanf("%2d%*3d%3d",&a,&b);当输入12345678时,a得到12,%*3d表示跳过2列,b得到678

案例:

#include <stdio.h>int main()
{int a,b;scanf("%3d%3d",&a,&b);// 输入1234567,a=123,b=456
}
  • 当用于输入整型数据的格式说明符中没有宽度说明时,则在具体输入数据时分为以下两种情
    况:

    ① 如果各格式说明符之间没有其它字符,则在输入数据时,两个数据 之间用"空格"、或"Tab"、或"回车"来分隔。

    ② 如果各格式说明符之间包含其它字符,则在输入数据时,应输入与 这些字符相同的字符作为间隔。

    例如,设有如下说明

    int a,b;

    float c,d;

    现要利用格式输入函数输入a=12,b=78,c=12.5,d=7.6。采用不同的格式说明,其输入数
    据的形式也是不同的。分别说明如下:

    • 若输入语句为 scanf(“%d%d%f%f”,&a,&b,&c,&d); (即格式说明符中没有宽度说
      明,各格式说明符之间也没有其他字符。)
      则输入数据的形式应为12 78 12.5 7.6↲ (两个数据之间用空格来分隔,当然也可用
      “Tab”或“回车”来分隔。)
    • 若输入语句为 scanf(“%d,%d,%f,%f”,&a,&b,&c,&d);(格式说明符中没有宽度说明,
      但各格式说明符之间有其它字符,即逗号)
      则输入数据的形式应为12,78,12.5,7.6↲ (即在输入的两个数据之间同时要输入逗号。)
    • 若输入语句 scanf(“a=%d,b=%d,c=%f,d=%f”,&a,&b,&c,&d); (即格式说明符中没
      有宽度说明,但各格式说明符之间有其它字符。)
      输入数据的形式应为 a=12,b=78,c=12.5,d=7.6 ↲ (即在输入的两个数据之间同时要输入
      这些非格式说明符的字符。)
  • 在用于输入的实型格式说明符中不能用m.n来指定输入的宽度和小数点后的位数(这是与输出的不同之处)。

    例如: scanf("%7.2f",&a); × 此用法是错误的

  • 为了便于程序执行过程中从键盘输入数据,在一个C程序开始执行时,系统就在计算机内存中开辟了一个输入缓冲区,用于暂存从键盘输入的数据。开始时该输入缓冲区是空的。当执行到一个输入函数时,就检查输入缓冲区中是否有数据;

扩展:输入输出缓冲机制

缓冲区的概念

  • 缓冲区(也称为缓存)是内存空间的一部分,用于暂存输入或输出的数据。
  • 在进行输入操作时,系统从外部设备(如键盘)读取数据,先放入缓冲区,程序再从缓冲区中读取数据。
  • 在进行输出操作时,系统先将数据放入缓冲区,然后在特定条件下(如缓冲区满、遇到特定字符、手动刷新等)再将缓冲区中的数据输出到外部设备(如屏幕)。

缓冲区的类型

C语言的缓冲区有三种类型:

  • 全缓冲:当缓冲区填满后,才进行实际的输入输出操作。例如,对磁盘文件的读写。 —
    window 全缓冲大小4096字节 linux 全缓冲大小1024字节
  • 行缓冲:当在输入和输出中遇到换行符时,执行实际的输入输出操作。例如,标准输入
    (stdin)和标准输出(stdout)。
  • 无缓冲:不进行缓冲,直接进行输入输出操作。例如,标准错误流(stderr)。

缓冲区的刷新条件

缓冲区的刷新(即将缓冲区中的数据实际输出到外部设备)通常发生在以下情况之一:

  • 缓冲区满:当缓冲区写满时,会自动刷新。
  • 遇到特定字符:如换行符(\n)。
  • 手动刷新:使用fflush(stdout)函数手动刷新输出缓冲区。
  • 程序关闭时:当程序结束时,缓冲区中的数据会被刷新。

缓冲区的实际应用

  • 提高效率:通过缓冲区,可以减少与外部设备的交互次数,提高数据传输的效率。
  • 处理输入输出:例如,使用scanf和printf函数时,数据先被放入缓冲区,然后按照特定的规则从缓冲区中读取或输出。

原理实现

在这里插入图片描述

注意事项

  • 在处理输入时,特别是连续输入多个数据时,需要注意缓冲区中可能残留的数据,这可能会影响后续的输入操作。
  • 在使用fflush(stdin)来清空输入缓冲区时,需要注意这是未定义行为,在标准C中并不推荐这种做法。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com