• c语言输入输出及缓冲区


    printf和scanf的作用是程序和外设进行交互的接口,
    printf可以将程序输出到屏幕上或打印机上;
    scanf可以将键盘的字符输入到程序中;
    但是printf和scanf并不是让程序和外设直接交互的,因为直接交互的话,一是外设读写速度慢,而是频繁读写外设易造成损伤,
    因此在程序和外设之间,c语言在内存中增加了输入缓冲区和输出缓冲区,用于提高程序和外设读写的响应速度,详情见下文。

    printf

    printf的作用是在程序中输出指定内容到设备上:

    printf("hello world!\n");
    
    • 1

    格式控制符

    命令功能
    %d十进制有符号整数
    %u十进制无符号整数
    %f浮点数
    %s字符串
    %c单个字符
    %p指针的值
    %e指数形式的浮点数
    %x, %X无符号以十六进制表示的整数
    %o无符号以八进制表示的整数
    %g把输出的值按照%e或者%f类型中输出长度较小的方式输出
    %p输出地址符
    %lu32位无符号整数
    %llu64位无符号整数

    转义字符

    命令功能
    \n换行
    \f清屏并换页
    \r回车
    \tTab符
    \xhh表示一个ASCII码用16进表示

    scanf

    # include 
    int scanf(const char *format, ...);
    scanf("%d%d", &i, &j);
    
    • 1
    • 2
    • 3

    scanf的作用是输入指定内容到变量中;
    格式化控制符的作用是将键盘的内容格式化后保存到变量中;
    需要注意的是,scanf的变量参数是指针格式,普通变量一定要取址。
    输入数据时,遇到三种情况则默认输入结束。第一,遇到空格,回车,tab键。第二,规定的宽度结束时。第三,非法输入。

    格式化控制符

    命令功能
    %c把输入解释成一个字符,如果前边加一个空格,即" %c",那么的scanf会忽略输入设备前边的空白项,直到遇到第一个字符,并只读区一个字符。
    %d把输入解释成一个有符号十进制整数
    %e,%f,%g,%a把输入解释成一个浮点数(%a是C99的标准)
    %E,%F,%G,%A把输入解释成一个浮点数(%A是C99的标准)
    %i把输入解释成一个有符号十进制整数
    %o把输入解释成一个有符号的八进制整数
    %p把输入解释成一个指针(一个地址)
    %s把输入解释成一个字符串:输入的内容以第一个非空白字符作为开始,并且包含直到下一个空白字符的全部字符
    %u把输入解释成一个无符号十进制整数
    %x,%X把输入解释称一个有符号十六进制整数

    缓冲区

    缓冲区是c语言为加速程序和外设的读写速度,而维护的一块内存区域,
    程序运行时,CPU从内存中读取程序数据,当程序需要对外设进行读写时,内存就需要和外设进行读写,而外设的读写速度很慢,因此c语言在内存中开辟了缓冲区,使大部分和外设交互的操作都在内存中进行。

    printf并不会逐个字符显示在屏幕上,而是先存在缓冲区,在特定的时机,将缓冲区一起显示在屏幕上:

    1.遇到\n
    2.程序结束          #include sleep(3);
    3.遇到输入语句
    4.当缓冲区满4k时
    5.fflush(stdout) 手动刷新

    缓存区机制可以提高数据的读写速度,并且可以让低速的输入输出设备与高速的CPU之间协调工作。

    scanf并不会从键盘逐个字符读入程序,而是先存在缓冲区,在特定的时机,将缓冲区一起输入到程序:

    1.当需要读取的是整型或者浮点型时,而缓冲区中的数据是字符或符号时,因此读取会失败,数据会残留在输入缓冲区中,就会影响接下来的所有数据的读取;
    解决方法:借助scanf返回值判断是否接受成功,如果接受过程有失败情况,可以先清理输入缓冲区,在重新循环接收数据,直到完全接收成功为止;

    2.fgets可以指定读取size-1个字符,如果有多余的会残留在输入缓冲区中,影响下一次输入;
    解决方法:scanf(“%*[^\n]”); 表示从缓冲区中接受任意字符并丢弃,只要不是\n就一直进行,遇到\n才停下

    3.当先输入整型或者浮点型数据,再紧接着输入字符、字符时,前一次残留的’\n’或空格,会影响字符和字符串的输入;
    解决方法:%c前面加空格 ,scanf(" %c",&ch);

    printf、scanf和缓冲区

    需要注意的是,使用回车键或者printf的语句中含有\n,回车符号也会记录在缓冲区,但是printf不会输出\n字符,scanf也不会读入\n字符,因此\n字符一直留在缓冲区,
    因此在使用scanf输入前,如果不想读取\n字符,就需要处理一下:

    例如:

    #include
    
    int main()
    {
    	char a=' ';
    	printf("hello\n");
    
    	scanf("%c",&a); //第一次输入,此时会读区printf里留下的\n,而直接略过;
    	scanf("%c",&a); //第二次输入,正常输入e
    
    	if(a==' ') printf("a=%c\n",a);
    	else printf("a=%c\n",a);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这个程序本来应该有两次输入,但是此时输入一次程序就继续走完了:

    hello
    e
    a=
    
    
    • 1
    • 2
    • 3
    • 4

    解决方案:
    在%c前边加个空格,这种格式可以忽略前边的空白字符(空格、tab):

    #include
    
    int main()
    {
    	char a=' ';
    	printf("hello\n");
    
    	scanf(" %c",&a);
    	scanf(" %c",&a);
    
    	if(a==' ') printf("a=%c\n",a);
    	else printf("a=%c\n",a);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    hello
    e
    r
    a=r
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    STM32WB55开发(1)----监测STM32WB连接状态
    手把手教你编写LoadRunner脚本
    Jedis入门及对Redis数据结构的操作
    从零基础转行渗透测试到如今20k,我经历了什么?
    ubuntu 更新
    跨平台应用开发进阶(三十三) :Android上架准备材料及流程介绍
    【前端必会】HtmlWebpackPlugin 和 SplitChunksPlugin 是什么?
    安装项目运行环境(python依赖包+allure)
    【数据结构】数据结构基础概念
    ARM架构与编程 · 基于IMX6ULL
  • 原文地址:https://blog.csdn.net/weixin_39759247/article/details/126321765