Linux系统编程 - 标准IO

Linux系统编程 - 标准IO

一、标准IO的三个标准流指针

系统为每个程序自动打开三个FILE * 流指针:

流指针 文件描述符 缓存类型 用途
stdin 0 行缓冲 标准输入(键盘)
stdout 1 行缓冲 标准输出(屏幕)
stderr 2 无缓冲 标准错误(屏幕)

特点

  1. 程序启动时自动创建

  2. 不需要fopen(),也不能fclose()

  3. 可直接用于标准IO函数

cpp 复制代码
#include <stdio.h>

int main() {
    // 使用标准流指针
    fprintf(stdout, "输出到屏幕\n");  // 等同于 printf
    fprintf(stderr, "错误信息\n");    // 立即输出,无缓冲
    fgetc(stdin);                    // 从键盘读取
    return 0;
}

二、标准IO缓存机制

1. 缓存类型对比

缓存类型 大小 刷新条件 适用对象
行缓冲 1024字节 1. 遇到\n 2. 缓冲区满 3. 程序结束 4. fflush() stdinstdout(终端设备)
全缓冲 4096字节 1. 缓冲区满 2. 程序结束 3. fflush() 4. fclose() 普通文件(磁盘文件)
无缓冲 0字节 立即输出 stderr

2. 缓存刷新示例

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    // 行缓冲示例
    printf("Hello");      // 不立即输出(无\n)
    printf(" World");     // 不立即输出
    sleep(2);
    printf("\n");         // 遇到\n,刷新输出
    
    // 全缓冲示例
    FILE *fp = fopen("test.txt", "w");
    for(int i = 0; i < 5000; i++) {
        fputc('A', fp);   // 缓冲区满4096字节时才会写入文件
    }
    fflush(fp);           // 手动刷新缓冲区
    
    // 无缓冲示例
    fprintf(stderr, "立即输出的错误信息\n");
    
    fclose(fp);
    return 0;
}

3. 强制刷新缓存

cpp 复制代码
#include <stdio.h>

int main() {
    // 刷新标准输出缓存
    printf("正在处理...");
    fflush(stdout);       // 立即输出,不等待\n
    
    // 刷新文件缓存
    FILE *fp = fopen("data.txt", "w");
    fputs("重要数据", fp);
    fflush(fp);           // 立即写入文件,防止数据丢失
    
    // 设置缓存模式
    setvbuf(stdout, NULL, _IONBF, 0);  // 设置为无缓冲
    setvbuf(fp, NULL, _IOFBF, 4096);   // 设置为全缓冲,大小4096
    
    fclose(fp);
    return 0;
}

三、标准IO文件定位

1. 文件定位函数

cpp 复制代码
#include <stdio.h>

int main() {
    FILE *fp = fopen("test.txt", "r+");
    if(fp == NULL) {
        perror("fopen");
        return -1;
    }
    
    // 1. fseek - 移动文件指针
    fseek(fp, 0, SEEK_SET);     // 移动到文件开头
    fseek(fp, 10, SEEK_CUR);    // 从当前位置向后移动10字节
    fseek(fp, -5, SEEK_END);    // 从文件末尾向前移动5字节
    
    // 2. ftell - 获取当前位置
    long pos = ftell(fp);
    printf("当前位置:%ld字节\n", pos);
    
    // 3. rewind - 重置到文件开头
    rewind(fp);
    printf("重置后位置:%ld字节\n", ftell(fp));
    
    // 示例:计算文件大小
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    printf("文件大小:%ld字节\n", size);
    rewind(fp);
    
    fclose(fp);
    return 0;
}

2. SEEK_宏定义

复制代码
#define SEEK_SET    0   // 从文件开头
#define SEEK_CUR    1   // 从当前位置
#define SEEK_END    2   // 从文件末尾

四、选择原则

何时使用标准IO?

  1. 处理普通文件,需要缓冲提高性能

  2. 需要格式化输入输出(printf/scanf)

  3. 需要行操作(fgets/fputs)

  4. 跨平台应用

相关推荐
wj3055853787 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
吃好睡好便好7 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
abigriver7 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
仰泳之鹅8 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
wangqiaowq8 小时前
windows下nginx的安装
linux·服务器·前端
nashane8 小时前
HarmonyOS 6学习:CapsLock键失效诊断与长截图完整实现指南
学习·华为·harmonyos
YYRAN_ZZU8 小时前
Petalinux新建自动脚本启动
linux
charlie1145141918 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
Agent手记9 小时前
异常考勤智能预警与处理与流程优化方案 | 基于企业级Agent的超自动化实战教程
运维·人工智能·ai·自动化
于小猿Sup9 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶