第二周学习笔记
20201303张奕博
I/O 库函数
I/O库函数与系统调用
系统调用函数
- open( ):打开和创建文件
- 使用例子int open(const char * pathname, int flags, mode_t mode);
- read( ):读文件
- read[1] (int fd, void *buf, size_t count);
- write( ):写文件
- write (int fd, const void * buf, size_t count);
I/O库函数及其算法
-
fopen( ):以指定的形式打开文件
r:以只读方式打开文件,该文件必须存在。
r+:以读/写方式打开文件,该文件必须存在。
rb+:以读/写方式打开一个二进制文件,只允许读/写数据。
rt+:以读/写方式打开一个文本文件,允许读和写。
w:打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。
w+:打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。
a+:以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。
wb:以只写方式打开或新建一个二进制文件,只允许写数据。
wb+:以读/写方式打开或建立一个二进制文件,允许读和写。
wt+:以读/写方式打开或建立一个文本文件,允许读写。
at+:以读/写方式打开一个文本文件,允许读或在文本末追加数据。
ab+:以读/写方式打开一个二进制文件,允许读或在文件末追加数据。 -
fread( ):从给定流 stream 读取数据到 ptr 所指向的数组中。
n=read(fd,fbuffer,BLKSIZE);
-
fwrite( ):把 ptr 所指向的数组中的数据写入到给定流 stream 中.
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
- buffer:指向数据块的指针
- size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
- count:数据个数
- stream:文件指针
-
fclose( ):关闭流 stream。刷新所有的缓冲区。
int fclose( FILE *fp );
I/O库模式
-
字符模式I/O
int fgetc(FILE *fp);
该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
int ungetc(int c, FILE *fp);
如果成功,则返回被推入的字符,否则返回 EOF,且流 stream 保持不变。
int fputc(int c, FILE *fp);
如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。 -
行模式I/O
- char *fgets(char *buf, int size, FILE *fp);
从fp中读取最多的为一行(以/n结尾)的字符。 - int fputs(char *buf,FILE *fp);
将buf中的一行写入fp中。
- char *fgets(char *buf, int size, FILE *fp);
-
格式化I/O
格式化输入(注意类比思维)scanf(char *FMT,&items);
fscanf(fp, char *FMT,&items);
格式化输出printf(char *FMT,items);
fprintf(fp,char *FMT,items)
-
内存中的转换函数
sscanf(buf,FMT,&items);
sprintf(buf, FMT, items);
-
其他I/O库函数(了解即可)
-
限制混合fread-fwrite
当某文件同时进行读、写操作时,会限制混合使用fread()和fwrite(),注意两者之间至少有一个fseek()或者ftell()
(本代码没有设置具体文件,所以编译不通过!)
文件流缓冲
- 无缓冲:从非缓冲流中写入或读取的字符将尽快单独传输到文件或从文件中传输。
- 行缓冲:遇到换行符时,写入行缓冲流的字符以块的形式传输。
- 全缓冲:写入全缓冲流或从中读取的字符以块大小传输到文件或从文件传输。这是文件流的正常缓冲方案。
setvbuf(FILE *stream,char *buf , int node,int size)
变参函数
在I/O中 printf()相当独特,多种类型的可变数量参数都可以调用它
项目实战
- 基于此次所学内容我写了一个读取一个文件的大写字母变成小写字母到另一个文件的程序
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#define INPUT_FILE "tmp1.txt"
#define OUTPUT_FILE "tmp2.txt"
int main(void)
{
char c;
FILE *fin, *fout;
fin = fopen(INPUT_FILE, "r");
if (!fin) {
perror(INPUT_FILE);
exit(1);
}
fout = fopen(OUTPUT_FILE, "w");
if (!fout) {
perror(OUTPUT_FILE);
exit(2);
}
while ((c = fgetc(fin)) != EOF) {
if (isupper(c) || islower(c))
c ^= 0x20;
fputc(c, fout);
}
return 0;
}
- 使用GCC编译
遇到的问题
I/O库中的标准I/O和文件I/O有啥区别?
解答:https://blog.csdn.net/a626785667/article/details/102122659
https://blog.csdn.net/SMith7412/article/details/103141197
- 标准I/O:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。
(1)全缓存:当填满标准IO缓存后才进行实际的IO操作。
(2)行缓存:当输入或输出中遇到新行符时,标准IO库执行IO操作。
(3)不带缓存:stderr就是了。 - 文件I/O:文件IO称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linux或unix平台。
- 区别
- 标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区),还创建了一个包含文件和缓冲区相关数据的数据结构。低级I/O一般没有采用缓冲,需要自己创建缓冲区,不过其实在linix或unix系统中,都是有使用称为内核缓冲的技术用于提高效率,读写调用是在内核缓冲区和进程缓冲区之间进行的数据复制。
- 文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符,标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。对于不同设备得特性不一样,必须有不同api访问才最高效。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/288621.html