stdio (标准IO)stdio 的一系列函数
sysio (系统调用IO / 文件IO)
系统IO是内核接口, 标准IO是C标准库提供的接口, 标准IO内部使用了系统IO
标准IO会合并系统调用, 可移植性好, 因此在两者都可以完成任务的情况下, 优先使用标准IO
详细参考man(3); FILE类型贯穿始终, FILE类型是一个结构体fopen(): 产生FILE
面试题:errno问: 能否通过语句2得到值为"xbc"的字符串?复制代码
- char *ptr = "abc";
- ptr[0] = 'x'; // 语句2
gcc编译会报错(修改常量值), 但Turbo C一类的编译器编译出的程序会运行通过
mode必须以表格中的字符开头符号模式r以只读形式打开文件, 打开时定位到文件开始处r+读写形式打开文件, 打开时定位到文件开始处w写形式打开文件, 有则清空, 无则创建w+读写形式打开文件, 有则清空, 无则创建a追加只写的形式打开文件, 如文件不存在, 则创建文件; 打开时定位到文件末尾处 (文件最后一个有效字节的下一个位置)a+追加读写的形式打开文件, 如文件不存在, 则创建文件; 读位置在文件开始处, 而写位置永远在文件末尾处
注意:
- r和r+要求文件必须存在
- mode可以追加字符b, 如rb/r+b, b表示二进制流, 在POSIX环境(包括Linux环境)下, b可以忽略
面试题:FILE *问: 语句2是否会报错?复制代码
- FILE *fp;
- fp = fopen("tmp", "r+write"); // 语句2
并不会, fopen函数只会识别r+, 后面的字符会被忽略
有逆操作的, 返回指针的函数, 其返回的指针一定指向堆上某一块空间关闭操作
如无逆操作, 则有可能指向堆, 也有可能指向静态区
公式: 权限 = 0666 & ~umaskumask的值可以通过umask命令查询, 该值主要用于防止权限过松的文件出现
问题:
假设有一文件:问: 用fgets(buff, 5, file)语句读取该文件, 需要几次才能读完?复制代码
- abcd
2次, 第一次读取到"abcd", 第二次读取到"\n"
问题:
要通过fread()从文件中读取字符串, 每次读取10个字符
- 假设文件中的有效字符数远大于10, 则2个语句各返回几?
语句1返回10(读到了10个大小为1的对象)复制代码
- // 语句1
- fread(ptr, 1, 10, fp);
- // 语句2
- fread(ptr, 10, 1, fp);
语句2返回1(读到了1个大小为10的对象)
语句1返回5, 而语句2返回0
- 假设文件中的有效字符数不足10个(比如5个), 则2个语句各返回几?
另外, 语句二返回0后, 它究竟读了多少个字符, 也无从得知; 因此, 如果要通过fread()从文件中读取字符串, 则一定要使用语句1的方法!
注意:printf & scanf
用fread()或fwrite()操作文件, 最好还是只做存取单一大小的数据(例如: 单一类型的结构体数据)的操作; 尽管如此, 这样的操作依然是有风险的, 因为一旦文件中由于各种原因含有了其他的数据, 那么fread()就会彻底失灵
注意:
尽管printf一族提供了大量的输出函数, 但是这些函数还是不能完全解决问题
sprintf和snprintf中, str不能自行增长, 因此不能解决需要输出长字符串的需求
注意:年-月-日
使用scanf一族时, 是不清楚要输入进来的数据有多长的
因此要注意, 输入文本的长度是否大于缓冲区的大小
由于ftell的返回值的类型为long, 而又不可能为负数, 因此其值域(在64位机器上)为$[0, 2^32 - 1]$, 因此利用ftell和fseek一同工作时, 只能定位2G大小的文件由于ftell有值域限制, 因此有了fseeko和ftello:
注意:刷新缓冲区
fseeko和ftello是POSIX环境的方言, C89和C99标准对其没有定义
缓冲区的作用: 大多数情况下是好事, 合并系统调用读取完整一行
行缓冲:
换行的时候刷新, 缓冲区满了的时候刷新, 强制刷新
全缓冲:
缓冲区满了的时候刷新, 强制刷新(默认, 只要不是终端设备)
无缓冲:
如stderr, 需要立即输出的内容
可以利用setvbuf修改缓冲模式
注意:mygetline
- 不需要自己为缓冲区分配空间, lineptr可为一个值为NULL的指针变量的地址
- getline只能在GNU C环境中使用
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |