一,printf和scanf函数
1,printf一族函数
printf是按照对应的format进行输出的,输出是放在终端的
fprintf是按照对应的流,将这个格式输出到对应的流里面
(这个函数可以将对应的报错和警告输入到对应的文件里面,不输出到终端,这样更加清楚观看)sprintf是按照这个格式,将此放到对应的字符数组里面
snpritf是为了解决这个sprintf不检查这个数组溢出的问题的,防止数组越界
2,重定向的概念
(1)、核心概念铺垫
在 Linux/UNIX 系统中,每个进程默认打开 3 个文件描述符(可以理解为 "文件句柄"):
- 0 (stdin):标准输入(默认是键盘)
- 1 (stdout):标准输出(默认是终端屏幕)
- 2 (stderr):标准错误(默认也是终端屏幕,用于输出错误信息)
重定向的本质就是:改变这 3 个描述符的默认指向(比如从屏幕改成文件)。
(2)、常用重定向符号及用法
1. 标准输出重定向
>/>>表格
符号 作用 示例 说明 >覆盖式重定向 echo "hello" > /tmp/out.txt将 echo的输出写入out.txt,如果文件已存在会清空原有内容>>追加式重定向 echo "world" >> /tmp/out.txt将内容追加到文件末尾,不会清空原有内容 注意:
>等价于1>(显式指定 stdout),比如ls -l 1> /tmp/ls.txt和ls -l > /tmp/ls.txt效果完全一样。2. 标准错误重定向
2>/2>>表格
符号 作用 示例 说明 2>覆盖式重定向错误 ls /nonexist 2> /tmp/error.txt将 ls的错误信息写入error.txt,覆盖原有内容2>>追加式重定向错误 cat /fakefile 2>> /tmp/error.txt将错误信息追加到文件末尾 3. 同时重定向标准输出和标准错误
这是最常用的场景(比如把命令的正常输出和错误都保存到文件):
- 方式 1(推荐,兼容所有 shell):
command > /tmp/all.log 2>&1
- 解释:
2>&1表示 "把 stderr(2)重定向到 stdout(1)当前指向的位置"(也就是/tmp/all.log)- 方式 2(bash/zsh 简化写法):
command &> /tmp/all.log
- 解释:
&>等价于> file 2>&1,更简洁- 追加写法:
command >> /tmp/all.log 2>&1或command &>> /tmp/all.log示例:
bash# 把ls的正常输出和错误都追加到日志文件 ls /etc /nonexist >> /tmp/ls_all.log 2>&14. 标准输入重定向
<表格
符号 作用 示例 说明 <重定向标准输入 cat < /tmp/out.txt让 cat从out.txt读取内容,而不是键盘<<此处文档(Here Document) cat << EOF > /tmp/hello.txtHello WorldEOF输入到 EOF为止的内容,写入hello.txt(常用于脚本中写多行内容)示例(用
<实现批量输入):
bash# 把文件内容作为输入传给wc命令(统计行数) wc -l < /etc/passwd3,scanf一族函数
fscanf就是将特定流的东西按照这个格式放到对应的地址
sscanf就是将这个字符串按照对应的格式放到对应的地址
注意这个是没有限制大小的,所以无法预测这个大小是否匹配会出现问题二,fseek和ftell函数
1,fseek函数
fseek函数是用来修改文件指针的位置的。
当用
fopen()打开文件后,系统会为这个文件分配一个文件指针 (不是FILE*类型的指针变量,而是记录当前读写位置的 "游标"):
- 默认情况下,刚打开文件时,指针指向文件开头;
- 每读写一个字节,指针会自动向后移动 1 位;
fseek()的作用就是手动修改这个指针的位置,实现 "跳着读 / 写" 文件。
cpp#include <stdio.h> #include <stdlib.h> int main() { FILE *fp = fopen("test.txt", "r"); if (fp == NULL) { perror("fopen failed"); exit(1); } // 先读2个字符,指针会自动后移 char c1 = fgetc(fp); char c2 = fgetc(fp); printf("读取前2个字符:%c%c\n", c1, c2); // 用fseek跳回文件开头(基准是SEEK_SET,偏移0) fseek(fp, 0, SEEK_SET); // 重新读第一个字符,验证指针位置 char c3 = fgetc(fp); printf("跳回开头后读取的字符:%c\n", c3); fclose(fp); return 0; }打开一个名为
test.txt的文件,先读取前两个字符,然后通过fseek()把文件指针跳回文件开头,再重新读取第一个字符,以此验证fseek()确实能手动调整文件读写指针的位置2,ftell函数
这个是用来返回文件位置指针的位置在哪里位置的
返回值为long
3,long类型问题
文件位置指针的位置不可能为负数,只可以为正数
由于在32为机器里面,long为有符long类型,范围为-2^31 ~ 2^31,那么这个这个缺陷就很明显,这个文件的大小不可以超过2G,所以为此又有了fseeko和ftello解决这个问题,但是这个适合在linux里面,所以移植性差,但是fseek和ftell的移植性好
这里说,这个off_t,在不同情境下的位数不一样,要想扩大至64位数,在编译的适合就要将
_FILE_OFFSET_BITS = 64编译进去,这样无论在什么情境下都是由64位的
三,文件位置函数和缓冲区刷新函数
1,文件位置函数
fseek函数是用来修改文件指针的位置的。
ftell函数用来返回文件位置指针的位置在哪里位置的。
然后fseek函数有三种方式
SEEK_SET 表示文件的开头
SEEK_CUR 表示文件的当前位置
SEEK_END 表示文件的末尾
fseek(fp, 0, SEEK_SET); 流,偏移量,当前位置
ftell也可以用于查看文件大小,跳到最后一行,然后一查看就知道有多少字节数。
2,下载软件的机制
下载软件首先会创建一个空洞文件,比如要下载的文件大小为2G,那么这个空洞文件大小也为2G,然后这里面存放的全部都是/0,然后使用多进程来讲文件全部写入到这个空洞文件完成下载。
3,缓冲刷新函数
缓冲的三种机制
1,行缓冲机制:换行的时候就进行刷新缓冲 (如这个标准输出就是)
2,全缓冲机制:要等缓冲满了才进行刷新缓冲(这个是文件默认的)
3,无缓冲进制:强制刷新缓冲(这个比如fflush函数就会这样)
不难看到第一行是没有打印出来得,如果在输出后面加一个换行或者ffluhs(NULL)就可以输出出来了
然后厘米是NULL得话就表示全部打开的流都刷新一遍
四,getline函数
getline函数是用malloc函数先创建一个空间,然后如果这个空间大小不够的话,那就要用relloc来扩展这个空间大小,直到可以装下。
1,bug问题
getline函数里面的要有对应的这个行创建的一个空间,然后后面就开辟一个n的初始大小的空间,然后获取这个行在哪一个流stream里面
这里面的lineptr指针和n是需要进行初始化的,如果没有进行初始化就会产生bug
因为这个不进行初始化,就无法判断这个是否是第一次用,那么就会里面的封装的方法就会出现bug,导致计算出来数据不对
2,可控的内存泄露
getline的实现就是用malloc创建空间,然后用relloc来进行衔接内存大小,在此过程中是没有释放这个内存的,所以这个时候就会产生内存泄露,这里不建议释放,因为你不知道这个内置函数的方法是怎么实现的,比如这里面如果用new,就要用delete来进行释放才可以。我们也可以自己修改一下这个函数使得这个函数好用
【Linux系统编程】文件IO 标准IO
一只自律的鸡2026-02-23 10:38
相关推荐
郝学胜-神的一滴1 小时前
Python中的del语句与垃圾回收机制深度解析EverydayJoy^v^2 小时前
Linux Shell 高级编程(2)——sed小义_2 小时前
【Kubernetes】(二)k8s基础Java后端的Ai之路2 小时前
在一个 Python 脚本中导入另一个脚本的功能清水白石0082 小时前
《解锁 Python 潜能:从异步基石到 pytest-asyncio 高级测试实战与最佳实践》三无少女指南2 小时前
开发者环境配置最佳实践:编辑器Cursor ,VS Code的上位体验实现 AI 与 WSL 联动2301_805348972 小时前
Haproxy的介绍以及配置示例BHXDML2 小时前
VMware 安装 Ubuntu 24.04 详细步骤Pr Young2 小时前
有限状态机
fscanf就是将特定流的东西按照这个格式放到对应的地址





