Linux系统编程——标准IO

目录

一、Linux文件类型

二、命令行参数

1.命令行参数的核心结构

2.打印命令行参数

三、标准IO库

1.打开文件(fopen)

2.读写文件

1)字符级读写

2)行级读写

3)块级读写

3.关闭文件(fclose)


一、Linux文件类型

Linux 系统中一切皆文件,但不同文件有着不同的属性和用途。通过 ll(ls -l的别名)命令查看文件时,输出结果第一列的第一个字符就代表了文件类型,共 7 种核心类型,具体如下:

类型标识 文件类型 特点与应用场景
d 目录文件 用于存储文件和子目录,可通过cd命令进入,类似 Windows 的文件夹
l 软链接文件 相当于 Windows 的快捷方式,指向源文件 / 目录,删除链接不影响源文件
- 普通文件 存储实际数据,如代码文件(1.c)、可执行文件(a.out)、文档、视频等
c 字符设备文件 按字符流传输数据的设备,如键盘、鼠标、串口,数据传输有序且体积小,大部分设备属于此类
b 块设备文件 存储设备(硬盘、U 盘、光盘),按 512 字节 / 块传输,支持随机访问
s 套接字文件 用于进程间网络通信(TCP/UDP),常见于/tmp或服务程序的通信目录
p 管道文件 用于同一主机上的进程间通信(IPC),数据传输后自动清空,不持久化存储

示例:

drwxrwxr-x 10 linux linux 4.0K Sep 6 2021 .vimplus/(目录文件)

lrwxrwxrwx 1 linux linux 27 Sep 5 2021 .vimrc -> /home/linux/.vimplus/.vimrc(软链接文件)

-rw-rw-r-- 1 linux linux 3.4K Sep 22 11:28 .vimrc.custom.config(普通文件)

man 手册的核心查询规则:

man(manual)手册是 Linux 系统中最权威的帮助工具,可查询命令、函数、配置文件等所有系统相关内容。掌握其查询规则,能快速获取函数参数、返回值、使用示例等关键信息。

命令格式 功能说明
man man 查看 man 手册自身的帮助信息(含所有章节介绍)
man man > 文件名 将 man 手册的帮助信息保存到文件
man xxx 默认查询 xxx 的帮助(优先匹配最小章节号)
man 1 xxx 查看 xxx命令的帮助(第 1 章节)
man 2 xxx 查看 xxx系统调用函数的帮助(第 2 章节)
man 3 xxx 查看 xxx标准库函数的帮助(第 3 章节)

二、命令行参数

1.命令行参数的核心结构

C 语言程序的 main 函数支持两个参数,用于接收命令行输入:

int main(int argc, char *argv[ ])

  • **argc:**argument count,命令行参数的总个数(包含程序名本身)。例如执行./a.out 1 2 3时,argc=4。
  • **argv:**argument vector,字符串数组,存储每个命令行参数的内容。argv[0]是程序名(如./a.out),argv[1]是第一个参数(如1),以此类推,最后一个元素argv[argc]为NULL。

2.打印命令行参数

下面的代码可遍历并打印所有命令行参数,帮助理解参数传递逻辑:

cpp 复制代码
int main(int argc, char *argv[])
{
    printf("argc is %d\n", argc);
    int i = 0 ;
    for(i = 0 ; i < argc; i++)
    {
        printf("%d %s\n", i, argv[i]);
    }
    return 0;
}

三、标准IO库

1.打开文件(fopen)

函数原型:

FILE *fopen(const char *pathname, const char *mode);

  • **pathname:**文件路径(绝对路径如/home/linux/test.txt,相对路径如test.txt)
  • **mode:**打开模式,决定文件的读写权限和初始位置,核心模式如下表:
打开模式 权限说明 注意事项
r 只读,读写位置从文件开头开始 目标文件必须存在
r+ 读写,读写位置从文件开头开始 目标文件必须存在
w 只写,读写位置从文件开头开始 会创建文件,并清空文件
w+ 读写,读写位置从文件开头开始 会创建文件,并清空文件
a 追加写,读写位置从文件末尾开始 会创建文件
a+ 追加写 + 读,写位置从文件末尾开始,读位置从文件开头开始 会创建文件

2.读写文件

1)字符级读写

**适用场景:**逐个字符处理文件(如文本文件的字符统计)。

| 函数 | 说明 | 原型 |
| fgetc | 从文件读取一个字符,到达结尾返回EOF | int fgetc(FILE *stream); |

fputc 向文件写入一个字符,写入错误返回EOF int fputc(int c, FILE *stream);
  • **c:**要写入的字符(虽然是int类型,但实际只取低 8 位)
  • **stream:**是文件流指针(如fp)

**示例:**用 fputc 和 fgetc 复制文件

cpp 复制代码
int main()
{
    // 打开源文件(只读)和目标文件(只写,不存在则创建)
    FILE *src_fp = fopen("source.txt", "r");
    FILE *dest_fp = fopen("dest.txt", "w");

    if (src_fp == NULL || dest_fp == NULL) 
    {
        printf("fopen failed\n");
        return 1;
    }

    int ch;  // 必须用int接收fgetc返回值,避免EOF(-1)与字符(0-255)混淆
    // 循环读取源文件字符,直到EOF
    while ((ch = fgetc(src_fp)) != EOF) 
    {
        fputc(ch, dest_fp);  // 将读取的字符写入目标文件
    }

    printf("File copied successfully!\n");
    // 关闭文件(先关目标文件,再关源文件,避免资源泄漏)
    fclose(dest_fp);
    fclose(src_fp);
    return 0;
}

2)行级读写

**适用场景:**按行处理文件(如读取配置文件、日志文件)。

| 函数 | 说明 | 原型 |
| fgets | 从文件读取一行字符,到达结尾返回NULL | char *fgets(char *s, int size, FILE *stream); |

fputs 向文件写入一个字符串 int fputs(const char *s, FILE *stream);
  • **s:**要写入的字符串(需以\0结尾)
  • **size:**数组大小(建议比预期行长大 2,预留\n和\0)
  • **stream:**文件流指针

**示例:**用 fgets 和 fputs 读取并打印文件内容

cpp 复制代码
int main() 
{
    FILE *fp = fopen("test.txt", "r");
    if (fp == NULL) 
    {
        printf("fopen failed\n");
        return 1;
    }

    char buf[100];  // 定义缓冲区数组
    // 循环读取每一行,直到EOF
    while (fgets(buf, sizeof(buf), fp) != NULL) 
    {
        fputs(buf, fp);
    }

    fclose(fp);
    return 0;
}

3)块级读写

**适用场景:**二进制文件(如图片、音频、可执行文件)或批量数据(如结构体数组)的读写,效率最高。

| 函数 | 说明 | 原型 |
| fwrite | 向文件写入指定数量的块数据 | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); |

fread 从文件读取指定数量的块数据 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • **ptr:**数据的首地址
  • **size:**每个块的字节数
  • **nmemb:**块的个数
  • **stream:**文件流指针

3.关闭文件(fclose)

文件操作完成后,必须调用 fclose 关闭文件,否则会导致:​

  • 缓冲区数据未刷新(部分数据未写入磁盘)
  • 系统资源泄漏(每个进程可打开的文件数有限)

函数原型:

int fclose(FILE *stream);

  • **stream:**要关闭的文件流指针

注意事项​:

  • 关闭文件后,不可再通过该文件流指针操作文件;
  • 建议先关闭写入流(如dest_fp),再关闭读取流(如src_fp),避免数据丢失;
  • 若程序异常退出(如未调用fclose),系统会自动关闭文件,但仍建议显式调用。
相关推荐
safestar201211 小时前
ES批量写入性能调优:BulkProcessor 参数详解与实战案例
java·大数据·运维·jenkins
来一颗砂糖橘11 小时前
负载均衡的多维深度解析
运维·负载均衡
楠奕11 小时前
CentOS7安装GoldenDB单机搭建及常见报错解决方案
linux·运维·服务器
GCTTTTTT12 小时前
远程服务器走本地代理
运维·服务器
剑锋所指,所向披靡!12 小时前
Linux常用指令(2)
linux·运维·服务器
做咩啊~12 小时前
6.增加一个flat网段
服务器·openstack
不愿透露姓名的大鹏12 小时前
Oracle归档日志爆满急救指南
linux·数据库·oracle·dba
飞Link12 小时前
逆向兼容的桥梁:3to2 自动化降级工具实现全解析
运维·开发语言·python·自动化
W.W.H.12 小时前
嵌入式常见的面试题1
linux·网络·经验分享·网络协议·tcp/ip
木白CPP13 小时前
DMA-Buffer内核驱动API文档
linux