markdown复制## 1. 输入输出函数基础认知
在C语言开发中,除了最基础的printf和scanf之外,标准库还提供了十余种专门针对不同场景设计的I/O函数。这些函数在文件操作、终端交互、数据处理等场景中各有优势。比如当我们需要按行读取配置文件时,fgets比fscanf更安全;处理二进制数据时,fread/fwrite又比文本操作更高效。
我见过不少开发者习惯性地只用printf/scanf,结果在遇到复杂I/O需求时要么代码冗长,要么性能低下。实际上,标准库中这些"特殊"的I/O函数都是为解决特定场景痛点而设计的。比如getchar()虽然简单,但在实现命令行交互时的即时响应上,比scanf("%c")更符合使用直觉。
## 2. 字符级I/O函数详解
### 2.1 单字符处理三剑客
getchar()和putchar()这对组合看似简单,但在终端交互中有独特优势:
```c
int ch;
while((ch = getchar()) != EOF) {
putchar(toupper(ch)); // 实时转大写输出
}
这种写法相比scanf+printf的组合,具有三个明显优势:
- 即时响应:无需等待回车键
- 内存安全:不会发生缓冲区溢出
- 错误处理:通过EOF明确知道输入结束
getc()和putc()则是它们的文件版本,典型用法:
c复制FILE *fp = fopen("log.txt","r");
int c;
while((c = getc(fp)) != EOF) {
putc(c, stdout); // 同时输出到屏幕
}
fclose(fp);
2.2 非缓冲I/O的妙用
getch()和getche()(conio.h)虽然不属于标准库,但在Windows平台开发控制台程序时非常实用。它们的核心区别在于:
- getch():无回显,适合密码输入
- getche():有回显,适合即时交互
典型应用场景:
c复制printf("请输入密码:");
char pwd[20];
for(int i=0; i<19; ){
pwd[i] = getch();
if(pwd[i] == '\r') break;
putchar('*'); // 手动显示掩码
i++;
}
pwd[i] = '\0';
3. 字符串处理函数深度解析
3.1 安全输入的最佳实践
gets()因为无法限制输入长度而被弃用,替代方案fgets()的正确用法:
c复制char buf[256];
fgets(buf, sizeof(buf), stdin);
// 处理可能的换行符
if(strlen(buf) > 0 && buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
对比sc
