【笔记】C_scanf缓存区机制

本文深入解析了scanf函数的缓存机制,包括其工作原理、连续输入处理、匹配失败情况及如何清空缓存。通过具体实例展示了scanf如何处理输入流中的数据,以及在匹配失败和遇到空格时的行为。

1.scanf缓存机制概念

scanf缓存机制是利用行缓存,在无\n字符出现前,输入的数据内容存入缓存,直到遇到\n,才将缓存清空进行赋值等操作。

2.实例1-连续输入

#include <stdio.h>

int main(){
	int a,b,c;
	scanf("%d",&a);//划重点这里的%d,而不是a=%d。下面一样
	scanf("%d",&b);
	scanf("%d",&c);
	printf("a=%d,b=%d,c=%d\n",a,b,c);
	return 0;
}

输入100 200 300 回车,当收到回车,从100开始匹配,匹配成功,赋值给a,继续往下遇到空格,忽略,匹配200赋值b。

3.实例2-匹配失败

#include <stdio.h>

int main(){
	int a=0,b=0;
	char str[30];
	printf("b=%d\n",b);
	scanf("%d",&a);
	scanf("%d",&b);
	scanf("%s",str);
	printf("a=%d,b=%d,str=%s\n",a,b,str);
	return 0;
}

输入 100 helloworld 回车
输出:

b=0
a=100,b=0,str=helloworld

当我们回车后,缓存区内有:100 helloworld,匹配发a匹配,赋值给a。helloworld匹配b,数据类型不同,匹配失败,缓存指针不动,helloworld继续匹配str,匹配成功,输出。

4.实例3-空格匹配失败

#include <stdio.h>

int main(){
	int a=1,b=2;
	scanf("a=%d",&a);
	scanf("b=%d",&b);
	printf("a=%d,b=%d\n",a,b);
	return 0;
}

输入:a=99 b=88
输出:

a=99,b=2

这里b=2,因为代码中的scanf(“b=%d”,&b),缓存中匹配不会忽视空白符号,会拿空白符号去进行匹配,空格匹配b=,匹配失败。但是如果将scanf代码改成:scanf("%d",b),输入 a=99 88,就能忽视空白符号匹配成功。
所以上述代码需要匹配成功必须把空白符号除去。
输入:a=99b=88
输出:

a=99,b=88

5.scanf清空缓存

清空缓存一般用在,输入两个数据,按照习惯,一般喜欢输入完一个数据后回车再进行输入下一个数据。

#include <stdio.h>
#pragma warning(disable:4996)//在vs2019中编写程序,内存泄漏警告,忽略警告

in main(){
	int a=0,b=0;
	scanf("a=%d",&a);
	scanf("b=%d",&b);
	printf("a=%d,b=%d,a,b);
	return 0;
}

这是第4点的代码,如果我们输入数据后
输入:a=100回车 //这个时候我们应该是希望下一个输入b,单数输出如下
输出:a=100,b=0
因为我们回车后直接开始读取缓存,如果在读取完a后清空缓存,再继续读取b,就能符合需求。

清空缓存的通用方式有两种:
1.getchar():读取缓存中的一个字符。

#include <stdio.h>

int main(){
	int a=0,b=0;
	char c;
	scanf("a=%d",&a);
	
	while((c=getchar())!='\n'&&c!=EOF);//清空缓存
	
	scanf("b=%d",&b);
	printf("a=%d,b=%d,a,b);
	return 0;
}

2.正则表达式scanf("%*[^\n]"); scanf("%*c");

#include <stdio.h>

int main(){
	int a=0,b=0;
	scanf("a=%d",&a);
	
	scanf("%*[^\n]"); scanf("%*c");
	
	scanf("b=%d",&b);
	printf("a=%d,b=%d,a,b);
	return 0;
}

还有非通用的方式:fflush(stdin)与rewind(stdin)
fllush(stdin):不同的编译器对他的支持是不同。
rewind(stdin):本身不支持清空缓存,但是在有些编译器上有效果。
这两种方式不是在所有编译器上都能够使用。

由于没有给出具体的报错信息,下面列举一些常见的使用 `gcc` 编译运行 C 语言代码时可能出现的报错及解决方法: ### 语法错误 如果代码中存在语法错误,如括号不匹配、分号缺失等,`gcc` 会在编译时输出错误信息,指出错误所在的行和大致原因。 示例代码: ```c #include <stdio.h> int main() { printf("Hello World!\n" // 缺少右括号 return 0; } ``` 解决方法:仔细检查错误信息提示的行,修正代码中的语法错误。对于上述示例,应在 `printf` 语句末尾添加右括号。 ### 头文件缺失 如果代码中使用了某个头文件,但没有正确包含,`gcc` 会提示找不到相关的函数或类型定义。 示例代码: ```c int main() { printf("Hello World!\n"); return 0; } // 缺少 #include <stdio.h> ``` 解决方法:在代码开头添加正确的头文件包含语句,如 `#include <stdio.h>`。 ### 库文件缺失 如果代码中使用了某些库函数,但编译时没有链接相应的库文件,`gcc` 会提示找不到函数定义。 示例代码使用了 `math.h` 中的 `sqrt` 函数: ```c #include <stdio.h> #include <math.h> int main() { double num = 16.0; double result = sqrt(num); printf("The square root of %lf is %lf\n", num, result); return 0; } ``` 编译命令可能需要添加 `-lm` 来链接数学库: ```bash gcc 12_scanf_demo.c -o 12_scanf_demo -lm ``` ### 权限问题 如果在运行可执行文件时提示权限不足,可能是文件没有执行权限。 解决方法:在 PowerShell 中,可以使用 `chmod` 命令(如果安装了相关的 Linux 工具集)为可执行文件添加执行权限: ```bash chmod +x 12_scanf_demo ``` ### 其他可能的问题 如果代码中使用了特定的 C 标准特性,而 `gcc` 默认的标准可能不支持这些特性,可以通过 `-std` 选项指定使用的 C 标准,例如: ```bash gcc -std=c99 12_scanf_demo.c -o 12_scanf_demo ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值