标准IO(库函数stdio.h)

📅 2026/8/14 13:29:22
标准IO(库函数stdio.h)
一、核心设计思想一切皆文件Linux系统将所有设备、目录、管道等都抽象为文件通过统一的接口操作。七种文件类型b—— 块设备文件如/dev/sdac—— 字符设备文件如/dev/input/mouse0d—— 目录文件-—— 常规文件l—— 软链接文件类似Windows快捷方式用ln -s创建s—— socket文件网络通信p—— 管道文件用mkfifo创建二、标准I/O基本操作流程三步走打开文件——fopen读写文件—— 按字符fgetc/fputc、字符串fgets/fputs或对象fread/fwrite操作关闭文件——fclose三、打开与关闭文件1.fopen—— 打开文件FILE *fopen(const char *pathname, const char *mode);功能打开文件并关联一个流给这个文件返回流指针后续操作都依赖此指针。参数pathname文件名的字符串。mode打开模式r只读文件必须存在。r :读写w只写文件存在则清空不存在则创建。w :读写a追加文件不存在则创建写入从末尾开始。a :读写读还是从头读从末尾写返回值成功FILE*指针流指针。失败NULL并设置全局错误码errno。其中 perror(自定义字符串) 错误原因2.fclose—— 关闭文件int fclose(FILE *stream);功能关闭流(stream)释放相关内存空间。返回值成功返回0失败返回EOF并且设置errno。注意同一文件不要多次fclose。五、按字符读写 ——fgetc/fputc1.fgetc—— 读一个字符int fgetc(FILE *stream);参数表示要进行读取的文件返回读取字符的ASCII码值失败或到达文件尾返回EOF-1。2.fputc()—— 写一个字符int fputc(int c, FILE *stream);成功返回写入字符的ASCII码值失败返回EOF。示例实现cp命令字符复制这里补充两种检查两个文件是否相同的方法第一种会跳转到文件中 如果一样的话 是灰色第二种如果一样的话 敲回车没有反应六、按字符串读写 ——fgets/fputs1.fgets()—— 读一行或指定长度char *fgets(char *s, int size, FILE *stream);从stream中最多读取size-1个字符数据储存在s中自动在末尾添加\0。读取结束条件遇到文件尾EOF遇到换行符\n\n会保存在buffer中读满size-1个字符。练习要读几次才可以全部读完 4次第一次是遇到\n结束自动补\0第二次是读满size-14自动补\0;第三次是又遇到\n也是读满自动补\0;第四次是读到文件末尾自动补\0.返回值成功返回s失败或文件尾返回NULL。2.fputs()—— 输出字符串int fputs(const char *s, FILE *stream);将字符串s输出到文件不输出\0也不自动加换行。成功返回非负数失败返回EOF注意手动ctrld产生EOF练习实现copy示例统计文件行数核心思路统计文件中\n的个数。倒数第二位置是不是\n这里用strlen,不可以sizeof,因为遇到\n会提前结束。⚠️ 注意fgets/fputs不适合复制二进制文件原因fputs遇到\0会停止输出导致二进制数据含\0丢失。七、按对象二进制读写 ——fread/fwrite用于读写二进制数据适合结构体等固定格式数据。size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);返回值成功返回读/写的元素个数失败或文件尾返回0。用char读 就是一个一个读10*1 10字节 输入1234 读3个char3个,就是123用short读 就是两个两个读10*2 20字节输入12345678 读3个short(6个)就是123456练习实现cat功能练习实现copy功能思路打开两个文件 一个读一个写 将读的文件偏移到开头创建一个和他同样大小的空洞文件 这时两个文件都在末尾 所以都用rewind偏移到开头 然后写入。八、定位函数(3个)1、2、long ftell(FILE *stream)获得文件偏移量的值 返回文件偏移量的值3、void rewind(FILE *stream)回到文件开头九、空洞文件 ---填充的都是0注意因为从0开始所以要减去1.练习把 3 个学生结构体数据以二进制形式写入stu.txt文件再从文件中读回这 3 个结构体并打印输出思路先打开一个w(读写)的文件将3 个学生数据写入到刚才打开的文件然后利用fseek将文件内部读写指针移动到文件开头因为前面fwrite写完数据后文件指针停在了文件末尾如果直接读会读不到内容 最后读取循环遍历打印读取到的学生信息。这里fflush(fp)强制刷新文件缓冲区把内存中缓存的数据立刻落地写到磁盘文件防止缓冲区滞留导致数据没保存getchar()阻塞暂停程序方便调试时中途打开文件查看内容。八、系统默认打开的三个文件流stdin—— 标准输入键盘-0文件描述符stdout—— 标准输出屏幕-1stderr—— 标准错误屏幕-2九、缓冲区概念提高效率十、格式化输出扩展printf(...); // 输出到 stdout fprintf(FILE *stream, ...); // 输出到一个文件中 sprintf(char *str, ...); // 输出到字符串危险可能溢出 snprintf(char *str, size_t size, ...); // 安全版指定大小十一、作业1、键盘输入(./a.out直接运行)2、输入重定向(./a.out hello.c):把文件内容代替键盘作为程序stdin的输入3、输出重定向(./a.out buf.txt)把程序stdout原本打印到屏幕的内容全部写入文件buf.txt总结终端交互时直接./a.outstdin 缓冲区大小1024stdout 行缓冲 1024stderr 无缓冲size0stdin 被文件重定向 hello.cstdin 变成全缓冲缓冲区扩容为 4096 字节stdout 依旧绑定终端保持 1024 行缓冲stdout 被文件重定向 buf.txtstdout 写入文件变为全缓冲缓冲区自动改成 4096 字节stderr 永远 0 缓冲核心规律输出到终端stdout 行缓冲换行就刷新输出到普通文件stdout 全缓冲写满缓冲区才刷新stderr 全程无缓冲立刻打印