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

相关推荐
2501_9458374312 分钟前
云服务器的技术本质与发展演进
服务器
越努力越幸运50813 分钟前
vue学习二:
javascript·vue.js·学习
POLITE325 分钟前
Leetcode 42.接雨水 JavaScript (Day 3)
javascript·算法·leetcode
Tim_1026 分钟前
【算法专题训练】36、前缀树路径和
算法
好易学·数据结构31 分钟前
可视化图解算法76:最大子数组和
数据结构·算法·leetcode·面试·动态规划·力扣·笔试
Jake_的技能小屋35 分钟前
端口号理解
学习
秋42738 分钟前
防火墙基本介绍与使用
linux·网络协议·安全·网络安全·架构·系统安全
取加若则_1 小时前
深入解析Linux进程优先级机制
linux·服务器
副露のmagic1 小时前
更弱智的算法学习 day13
学习·算法
点亮一颗LED(从入门到放弃)1 小时前
设备模型(10)
linux·服务器·前端