linux标准i/o,Linux 标准I/O笔记

三个标准输入输出

以下三个输入输出就像已经打开的文件流一样,可以直接拿来用

l 标准输入: /dev/stdin或FILENO_STDIN,shell代号0,对应键盘;

l 标准输出: /dev/stdout或FILENO_STDOUT,shell代号1,对应显示器;

l 标准错误输出: /dev/stderr或FILENO_STDERR,shell代号2,对应显示器。

三种缓冲缓冲用于减少对系统函数read/write的调用次数,提高读写效率

非缓冲IO:每次修改时都要进行一次系统IO调用,系统IO将修改内容写入到文件中缓冲IO:把文件的内容读到一块内存区域,每次修改都在内存区域中操作,最终修改完成后再调用系统IO写入到文件中,那块内存区域称为缓冲区

1.全缓冲:在缓冲区写满时输出到指定的输出端.比如对磁盘上的文件进行读写通常是全缓冲的.

2.行缓冲:在遇到'\n'时输出到指定的输出端.比如标准输入和标准输出就是行缓冲,回车后就会进行相应的I/O操作.

3.无缓冲:有什么就输出什么.比如标准错误输出,出错时立即显示出来.

可用fflush立即输出,不管缓冲区是否达到输出标准设置缓冲方式的函数有两个,分别为setbuf,setvbuf

打开、关闭

1.FILE *fopen(const char *restrict pathname, const char *restrict type)第一个参数为文件的路径,第二个参数为打开的方式,有读/写/添加/重写等选项

2.int fclose(FILE *fp)关闭打开的文件流,释放内存

读写

1.每次读写一个字符

getc/fgetc/getchar

putc/fputc/putchar

2.每次读写一行

fgets/gets

fputs/puts

3.每次读写一个对象

这种读写方式也称为二进制方式,由我们自己设定一次读几个字节(不是字符) ,以文本方式打开时通常是乱码

l size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp)

参数含义:从fp读取,读取的内容写到ptr指向的内存,每次读取size个字符,一共读nobj次

l size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp)

通常用于读取格式固定的文件,比如有个文件的内容如下:

0000,0001,0002,0003,0004, ...  ...  ... 9995,9996,9997,9998,9999,

从0000-9999的所有四位数,每个对象由4个数字组成,之间用逗号隔开那么我们读的时候就可以一次读5个字符

定位

用于在打开的文件中跳到指定位置进行读写

l fseek:跳转到指定的文件位置

l ftell:获取文件指针当前所在位置

l rewind:回到文件头

格式化

写:

l printf:格式化数据写到标准输出

l fprintf:格式化数据写到指定的流

l sprintf/snprintf:格式化数据写到指定的字符数组

读: scanf/fscanf/sscanf

例子1

缓冲直观感受,新建一个test.txt,向里面写入两行字符,在fflush前后各输出一次文件内容。因为文件是全缓冲,所以第一次没有内容输出,第二次fflush强制刷新缓冲区输出内容.另外fclose(fp)也会调用fflush刷新缓冲区.

#include #include

#define MAXLINE  1024char outbuf[MAXLINE];

//输出文件内容void showcontent(){

puts("----- start showcontent -------");

FILE *fp;

if((fp=fopen("./test.txt","r")) ==NULL){

perror("fopen error");

exit(-1);

}

while(fgets(outbuf,MAXLINE,fp) !=NULL){

puts(outbuf);

}

puts("----- end showcontent -------");

}

//w+模式打开,每次打开文件都会擦除原有内容再写入,如果文件不存在就创建void fullbuf(){

FILE *fp;

if((fp=fopen("test.txt","w+")) ==NULL){

perror("fopen error");

exit(-1);

}

fputs("This is fullbuf.",fp);

fputs("all content output at a time.",fp);

puts("before fflush");

showcontent();

fflush(fp);

puts("after fflush");

showcontent();

fclose(fp);

}

int main(){

fullbuf();

return 0;

}

例子2

在一些简单的单机游戏中,游戏角色的属性是用二进制方式保存的.如名称用char[length]来保存,等级用int来保存,经验值用unsigned int来保存,将这些属性结合在一起形成一个struct,在玩家退出游戏时调用fwrite保存起来,等玩家再次登录时调用fread读取属性。

下面的例子很简单,将五个people结构写入文件然后再读取出来

#include #include

struct people{

char name[10];

int age;

};

void readstruct(){

struct people man[10];

FILE *fp;

if((fp=fopen("./test.txt","r")) == NULL){

perror("fopen error");

exit(-1);

}

fread(man,sizeof(struct people),5,fp);

int i;

for(i=0;i<5;++i)

printf("%d. name=%s, age=%d\n",i+1,man[i].name,man[i].age);

fclose(fp);

}

void writestruct(){

struct people man[10];

int i;//输入并回车: first 1 second 2 third 3 fourth 4 fifth 5

for(i=0;i<5;++i){

scanf("%s",&man[i].name);

scanf("%d",&man[i].age);

}

FILE *fp;

if((fp=fopen("./test.txt","w+")) == NULL){

perror("fopen error");

exit(-1);

}

fwrite(man,sizeof(struct people),5,fp);

fclose(fp);

}

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

writestruct();

readstruct();

return 0;

你可能感兴趣的:(linux标准i/o)