第7章 输入与输出

1. 标准输入/输出基础

1.1 标准I/O函数概述

  • printf():格式化输出函数,支持多种数据类型转换
  • scanf():格式化输入函数,需注意变量地址传递
  • 字符I/O
    • getchar():从标准输入读取单个字符
    • putchar(c):输出单个字符
  • 字符串I/O(已废弃,不安全):
    • gets()/puts()

1.2 格式化输出详解

printf("格式字符串", 参数列表);
  • 格式说明符
    • %d:整数
    • %f:浮点数
    • %c:字符
    • %s:字符串
    • %p:指针地址
  • 修饰符
    • %5d:最小宽度5
    • %.2f:保留2位小数
    • %-10s:左对齐

重点难点

  • 格式字符串与参数类型必须严格匹配
  • 浮点数精度问题(float默认提升为double

2. 格式化输入

2.1 scanf()基本用法

scanf("格式字符串", &变量);
  • 必须使用取地址运算符&
  • 格式说明符printf()类似

2.2 常见问题

  • 缓冲区残留:换行符可能导致后续读取错误
  • 输入匹配失败:类型不匹配时返回EOF
  • 安全性问题:字符串输入易导致缓冲区溢出

解决方案

// 安全读取字符串
char buf[100];
fgets(buf, sizeof(buf), stdin);

3. 文件I/O操作

3.1 文件指针与基本操作

FILE *fp = fopen("文件路径", "模式"); 
fclose(fp);
  • 打开模式
    • "r":只读
    • "w":写入(清空原内容)
    • "a":追加
    • "rb"/"wb":二进制模式

3.2 文件读写函数

函数 描述
fprintf(fp, ...) 格式化写入
fscanf(fp, ...) 格式化读取
fgetc(fp)/fputc(c, fp) 字符I/O
fgets(buf, size, fp) 安全读取一行
fread()/fwrite() 二进制块I/O

重点难点

  • 二进制与文本模式区别(Windows换行符处理)
  • 文件指针位置控制fseek()/ftell()

4. 错误处理

4.1 错误检测函数

函数 作用
ferror(fp) 检查文件错误
feof(fp) 检测文件结束
perror("提示") 打印系统错误信息

4.2 最佳实践

FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
    perror("打开文件失败");
    exit(EXIT_FAILURE);
}

5. 高级I/O话题

5.1 可变参数函数

  • vprintf()系列函数
  • 自定义可变参数函数:
#include <stdarg.h>
void log_message(const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}

5.2 缓冲机制

缓冲类型 特点
全缓冲 缓冲区满时刷新(默认文件I/O)
行缓冲 遇到换行符刷新(标准输出)
无缓冲 立即输出(标准错误)

手动刷新

fflush(fp);  // 强制刷新缓冲区

6. 实际应用示例

6.1 文件复制程序

void file_copy(FILE *src, FILE *dst) {
    int c;
    while ((c = fgetc(src)) != EOF) {
        fputc(c, dst);
    }
}

6.2 CSV文件解析

while (fscanf(fp, "%[^,],%d,%f\n", name, &age, &score) == 3) {
    // 处理每条记录
}

7. 总结与最佳实践

7.1 关键原则

  1. 始终检查I/O函数返回值
  2. 优先使用安全函数(如fgets替代gets
  3. 明确缓冲区管理策略
  4. 区分文本与二进制I/O需求

7.2 常见陷阱

  • scanf()系列函数的安全问题
  • 文件打开未关闭导致资源泄漏
  • 未处理EOF条件导致的死循环

7.3 性能优化

  • 减少小数据量的频繁I/O操作
  • 使用块读写(fread/fwrite)处理大文件
  • 合理设置缓冲区大小

本章是C语言系统级编程的基础,掌握这些I/O技术对文件处理、数据解析等任务至关重要。建议通过实际项目(如日志系统、数据转换工具)加深理解。

posted @ 2025-05-12 17:26  MachineGaming  阅读(17)  评论(0)    收藏  举报