C_输入与输出
2026/7/12 3:51:45 网站建设 项目流程

缓冲区

缓冲区
cpu会一条条执行指令,当执行到scanf和printf指令,就需要往外部设备输出或倒输入数据
而cpu速度非常快,外部设备速度更不上,就会导致拖累Cpu速度。为了解决这个问题,设立了缓冲区。这个缓冲区位置在内存中。现在CPU往外部设备输出数据,不用直接,而是先往缓冲区(内存)里面输出,等到合适时间在输出到外部设备
缓冲区可分为三种:
满缓冲区
当缓冲区满的时候,数据才会刷新到目的地。
行缓冲区
printf就是行缓冲区。如果在不影响业务逻辑下,建议printf加\n
无缓冲区
stderr就是无缓冲区
面试题:缓冲区的作用?
平衡速度的差异。一方速度快,一方速度慢,可以加缓冲区平衡两者的速度差异。
扩展:Cpu的内部组成
里面有一个叫做Register内部寄存器(cpu的内存)
速度差异
Register>内存>外部设备
计算机采取读数据的方式是:
想要读取磁盘的数据,不会马上就去磁盘找,而是先在最快的Register看看有没有,没有就去内存里面看看有没有,最后再到磁盘里面找,这种方式也叫缓存命中

标准输入和输出

在c中,scanf和printf输入和输出,scanf从键盘做输入;printf打印,往屏幕做打印。
在window环境下scanf会报错,因为微软认为是不安全,会喊你用scanf_f,但是这_s是微软特有的,你去别的环境可能就会报错,所以还是用scanf,在微软可以使用
#define _CRT_SECURE_NO_WARNINGS 取消因为scanf的错误提示

标准输出printf()

printf函数的返回值是一个int类型:
在输出成功时,返回值表示函数实际输出的字符总数(不包括末尾的空字符)。
即输出成功时,返回值是一个非负数,最小也是0。
如果输出由于某些原因失败,那么返回值将会是一个负数。
printf函数将数据输出到stdout的行缓冲区,但要将这些数据真正展示到外部设备(如屏幕),
则需依靠stdout的自动刷新机制。为了增加输出的实时性和可预测性,一个常见策略是在输出字符串的末尾添加换行符\n”,这样可以立即触发缓冲区的刷新。这确保了待显示的信息能够迅速呈现,不会因其他因素延迟。
建议:
在不影响程序的逻辑的前提下,调用printf函数的格式字符串应当总是以换行符n结尾。

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(void) { int i, j; float x, y; i = 10;j = 20; x = 43.2892f;y = 5527.0f; printf("i=%d,j=%d,x=%f,y=%f\n", i, j, x, y); //输出百分号 printf("%%"); fLoat a = 3.1415926f; //printf转换说明中使用*字符代码2 printf("|%5.2f|",a); /* 打印结果是: 3.14 现在我改变需求,希望能够用变量在程序运行时期确定打印小数点后的位数以及打印结果的总宽度, 比如给定两个变量: printf转换说明中使用*字符 */ int width = 5; int point = 2; /* 那么该如何实现呢? 此时就需要用到转换说明中的特殊字符””,它的使用语法如下: printf转换说明中使用*字符 */ printf("|%*,*f|",width,point,a); printf("|%4f|\n", 3.14159f); printf("|%10f|\n", 3.14159f); printf("|%.4f|\n", 3.14159f); printf("|%4.1f|\n", 3.14159f); printf("|%04.1f|\n", 3.14159f); printf("|%4.1f|\n", 3.14159f); printf("|%-4.1f|n", 3.14159f); printf("|%+4.1f|\n", 3.14159f); return 0; }

标准输入scanF()

scanf函数的核心作用是从stdin缓冲区中读取字符形式的数据,并将其转换为特定类型的数据。
从实际效果看,scanf函数会根据格式字符串读取输入的内容,并将这些内容赋值给指定的变量。调用scanf函数时,首要参数也是格式字符串,紧随其后的参数是变量的地址,表示将读取到的值存放在哪个地址。
scanf函数会从左到右依次匹配格式字符串中的每一项:
如果匹配数据项成功,那么scanf函数会继续处理格式串的剩余部分;
如果匹配不成功,那么scanf函数将不再处理格式串的剩余部分,而会立刻返回。

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(void) { int i, j; float x, y; scanf("%d%d%f%f\n", &i, &j, &x, &y); /* 100 200 0.1 0.2 i=100, j=200, x=0.1, y=0.2 1-20.3-4.0e3 i=1, j=-20, x=0.3, y=-4.0e3 100a2000.10.2 i=100,j,x,y=随机值,因为a匹配不了 1002000.10.2 i=1002000, j=随机, x=随机, y=随机 j是int,0.10搞不了 */ //如果在scanf中,出现了普通字符。必须要原样写这个普通字符。 scanf("i=%d", &i); //在输入的时候,必须写i = 999这种。前面的i=一定要写。 // %c的匹配比较特殊。可以匹配任意多个空格,可以匹配换行符。 // 但是一般我们对%c的输入,肯定是某个非空白的字符 //建议:前面加一个空格 char ch; scanf(" %c", &ch); scanf("%d", &i); scanf("%c", &ch); //10a,这样子i和ch的值都是对的 /* 10换行符 a 这时候i是对的,ch就直接匹配换行符,而没有匹配那个a 这句话很多同学是知道的,但没有完全理解。 我们来看一段普通的scanf代码: */ }

缓冲区对scanf函数的影响-示例代码
int num;
char ch;
scanf("%d"&num);
scanf(" %c",&ch);
该行代码执行如果正常进行键盘录入:
100
A
最终num和ch的结果分别是100和A,但如果键盘录入:
100A
最终结果是什么呢?
实际上结果仍然是100和A,那么为什么呢?
这是因为当键盘录入100A时,这一段数据会被放入stdin缓冲区,缓冲区中已有数据100A,然后scanf开始从缓冲区中读数据。
第一个scanf以转换说明%d读取整数,所以num变量的最终取值是100,而缓冲区中的A字符,第一个scanf是不会管它的。因为当scanf函数遇到一个不属于当前项的字符时,就返回了。
第二个scanf以转换说明%c读取字符,也是从缓冲区中读,缓冲区不为空,且恰好存在一个字符A,于是ch的最终取值就是A。
所以,在需要连续录入的场景中,我们要特别注意缓冲区中数据的变化,避免因此引发的一些问题。

其它输入输出

printf/scanf = 屏幕 <-> 键盘
sprintf/sscanf = 字符串 <-> 变量
fprintf/fscanf = 文件 / 流 <-> 变量

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void test_1() { //sprintf → 往字符串里打印,作用:把数字、变量 变成 字符串,存到字符数组里 char str[20] = { 0 }; sprintf(str, "%d %d\n", 10, 20); //sscanf是输入,从字符串输入。可以将字符串转换位某种类型 //全称:string scan → 从字符串里读取数据 //作用:把字符串解析成数字、变量 int num = 100; sscanf(str, "%d", &num); printf("num=%d", num); } void test_2() { int num = 100; //fprintf:输出,往文件流里面输出 //全称:file print → 往文件 / 流里打印 //作用:往文件、屏幕、网络等 “流” 里输出内容 fprintf(stdout, "%d %d", 30, 60); //往屏幕输出30,60 //fscanf也是输入,只是是从文件里面输入 //全称:file scan → 从文件 / 流里读取 //作用:从文件、键盘等 “流” 里读数据 fscanf(stdin, "%d", &num); printf("num=%d", num); } int main(void) { test_1(); return 0; }

案例:分数相加

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(void) { /* 分子分母的输入,两个分数相加 1/2 + 3/4 1*4/2*4 + 3*2/4*2 这两个分数,相加。 */ int numerator1,denominator1;//第一个分数的分子和分母 int numerator2,denominator2;//第二个分数的分子和分母 //输入第一个分数 printf("请输入第一个分数(格式:a/b):"); scanf("%d/%d",&numerator1,&denominator1); //输入第二个分数 printf("请输入第二个分数(格式:a/b):"); scanf("%d/%d",&numerator2,&denominator2); //分数加法计算 int result_num = numerator1 * denominator2 + numerator2 * denominator2; int result_denom = denominator1 * denominator2; printf("两个分数之和为:%d/%d\n", result_num, result_denom); return 0; /* 假设,大家就是不知道。 怎么搞? 有一些东西不会,但是得让自己会起来。 第一种方式,google/bing搜索 按照词语的分隔搜索是最好的:分子 分母 化简 */ }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询