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. 跨平台应用

相关推荐
懂软件的胡子个哥31 分钟前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
m4Rk_42 分钟前
【论文阅读】Agent 记忆机制(77):TSM——让记忆回到事件真正发生的时间
论文阅读·人工智能·学习·开源·github
Zane19941 小时前
暴力字符串匹配失配就要把文本指针往回拉,KMP凭什么能让它一直往前走
算法
陈年老古董1 小时前
MediaPipe 姿态检测与脸部关键点检测
笔记·python·opencv·学习·dlib
云贝贝贝1 小时前
腾讯云 TDSQL(MySQL 版)性能优化与慢查询排障实战 6 招
运维·腾讯云
旺仔小馒头wang1 小时前
AI 智能手机发布会:赋予人类的五种新能力
人工智能·学习·音视频
人工智能培训1 小时前
未来三年,AI 落地的五个确定性判断
大数据·人工智能·学习·生活·ai写作
Lsetea1 小时前
证书没到期却报certificate has expired:OpenSSL定位中间证书与系统时间
运维·https·ssl证书·openssl·证书链
CCCCCCCCharlie1 小时前
Linux进程控制四大核心操作
linux·开发语言
LONGZETECH1 小时前
一线职教实测:风光 580 汽车故障诊断仿真系统,破解实车实训四大核心痛点
人工智能·学习·安全·架构·汽车