C语言I/O文件操作总结

/******************************************************************
***  标准I/O库
*** 对于标准I/O库,它们的操作是围绕流(stream)进行的
*** 用标准I/O库打开或者创建一个文件时,我们就将一
*** 个流和一个文件相关联
******************************************************************/
 
  对于ASCII字符集,一个字符用一个字节表示。对于国际字符集,一个字符可用多个字节表示。标准I/O文件流可用于单字节或多字节(“宽”)字符集。流的定向决定了所读、所写字符是单字节还是多字节。当一个流最初被创建时,它并没有定向。如若在未定向的流上使用一个多字节I/O函数,则将该流的定向设置为宽定向的。若在未定向的流上使用一个单字节I/O函数,则将该流的定向设置为字节定向的。
  只有两个函数可以改变流的定向。freopen函数清除一个流的定向;fwide函数设置流的定向。
  #include<wchar.h>
  int fwide(FILE *fp,int mode);
  若mode参数值为负,fwide将试图使指定的流是字节定向的。
  若mode参数值为正,fwide将试图使指定的流是宽定向的。
  若mode参数值为0,fwide将不试图设置流的定向,但返回标识该流定向的值

三种标准输入、输出、出错:
stdin
stdout
stderr 
 
缓冲:
  标准I/O提供了三种类型的缓冲
  (1)全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。对于驻留在磁盘上的文件通常采用全缓冲。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc函数获得需使用的缓冲区。
  (2)行缓冲。当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。当流涉及一个终端时,通常使用行缓冲。
   对于行缓冲有两个限制:
    第一、因为标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使还没有写一个换行符,也进行I/O操作。
    第二、任何时候只要通过标准I/O库要求从一个不带缓冲的流,或者一个行缓冲的流得到数据,那么就会造成冲洗所有行缓冲输出流。
  (3) 不带缓冲。标准库不对字符进行缓冲存储。标准出错流通常是不带缓冲的。
 
  void setbuf(FILE *restrict fp, char *restrict buf);
  int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
 
  setbuf函数打开或者关闭缓冲机制,参数buf是一个指定长度为BUFSIZ的缓冲区。buf设置为NULL ,则表示关闭缓冲区。
  setvbuf函数可以精确的指定所需的缓冲类型。这是用mode参数实现的:
   mode:
    _IOFBF 全缓冲
    _IOLBF 行缓冲
    _IONBF 不带缓冲
   如果指定一个不带缓冲区的流,则忽略buf和size参数。如果指定全缓冲或行缓冲,则buf和size可以选择的指定一个缓冲区和长度,如果该流是带缓冲的,而buf是NULL,则标准I/O库将自动的分配适当长度的缓冲区。适当长度指的是由常量BUFSIZ所指定的值。
  
打开流:
  FILE *fopen(const char *restrict pathname,const char *restrict type);
  FILE *freopen(const char *restrict pathname,const char *restrict type,FILE *restrict fp);
  FILE *fdopen(int filedes,const char *type);
  三个函数成功返回文件指针,失败返回NULL

(1)、fopen打开一个指定的文件
(2)、freopen在一个指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流。若该流已经定向,则freopen清除该定向。此函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出或标准出错; 
  (3)、fdopen获取一个现有的文件描述符,并使一个标准的I/O流与该描述符相结合。此函数常用于由创建管道和网络通信通道函数返回的描述符。因为这些特殊类型的文件不能用标准I/O fopen打开,所以我们必须先调用设备专用的函数以获得一个文件描述符,然后用fdopen使一个标准I/O流与该描述符相关联。
  type参数是对该I/O流的读、写方式

读和写流:
  一旦打开了流,则可以在三种不同类型的非格式I/O中进行选择,对其进行读写:
  1.每次一个字符的I/O。 一次读或写一个字符,如果流是带缓冲的,则标准I/O函数会处理所有缓冲。
  2.每次一行的I/O。 如果想要一次读或者写一行数据,则适用fgets和fputs。每行都以一个换行符终止。当调用fgets时,应说明能处理的最大行长。
  3.直接I/O。fread和fwrite函数支持这种类型的I/O。每次I/O操作读或写某种数量的对象,而每个对象具有指定的长度。这两个函数常用于从二进制文件中每次读或写一个结构。

一、每次一个字符的I/O:
1.输入函数:
int getc(FILE *fp);
int fgets(FILE *fp);
int getchar(void); //等价于getc(stdin)

这三个函数成功则返回下一个字符,到达文件尾或者出错返回EOF 为了 区分不同情况必须调用一下函数:
int ferror(FILE *fp);
int feof(FILE *fp);
成功返回非零,否则返回0
在大多数实现中,为每个流在FILE对象中维持了两个标志:
出错标志 和文件结束标志
void clearerr(FILE *fp);//清空错误标志和文件结束标志:

从流中读取数据之后,可以调用ungetc将字符再压送会流中
int ungetc(int c,FILE *fp); //成功返回c 否则返回EOF

2.输出函数:
int putc(int c,FILE *fp);
int fputc(int c,FILE *fp);
int putchar(int c);
三个函数成功返回c 失败返回EOF
  
二、每次一行的I/O
1.输入函数:
  char *fgets(char *restrict buf,int n,FILE *restrict fp);
  char *gets(char *buf); //从标准输入读。
  两个函数成功返回buf,失败返回NULL
  fgets 需要指明缓冲区buf的长度n,此函数一直读到换行符为止,读入的数据不能超多n-1个字符,否则读入的将是一个不完整的字符串。buf以NULL结尾。
2.输出函数:
  int puts(const char *str);//将一个以null结尾的字符串写到标准输出,null不写出。
  int fputs(const char *restrict str,FILE *fp);
  两个函数成功返回非负值,出错返回EOF
三、二进制I/O

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

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

两个函数返回成功读取或者写入的对象数。

ptr 为要读入或者写入的数据缓冲区, size为 每个对象的字节数, nobj为要读取或者写入的个数,fp为指定的流。

四、格式化I/O
1.格式化输出:
  int printf(const char *restrict format, ...);
  int fprintf(FIlE *restrict fp, const *restrict format, ...);
  //两个函数 成功返回输出字符数,出错返回负值。
  int sprintf(char *restrict buf,const char *restrict format, ...);
  int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
  //两个函数 成功返回存入buf中的字符数,若编码出错则返回负值。
2.格式化输入:
  int scanf(const char *restrict format, ... );
  int fscanf(FILE *restrict fp, const char *restrict format, ...):
  int sscanf(const char *restrict buf, const char *restrict format, ...):
  成功返回输入的项数,否则返回EOF
五、 定位流
有三种方式定位标准I/O流
1. ftell和fseek函数:
  long ftell (FILE *fp);//成功返回当前文件位置,出错返回-1
  int fseek (FILE *fp, long offset, int whence); //成功返回0,失败返回非零值
  void rewind(FILE *fp);//将流设置到文件的起始位置

  whence 的取值:
   SEEK_SET---------表示从文件的起始位置开始
   SEEK_CUR---------表示从文件的当前位置开始
   SEEK_END---------表示从文件的结束位置开始
  offset 值可正可负;

2. ftello 和 fseeko函数:
  off_t ftello(FILE *fp);//成功返回当前文件位置,出错返回-1
  int  fseeko(FILE *fp, off_t offset, int whence);//成功返回0,失败返回非零值
 
  和ftell与fseek函数相同;
3. fgetpos和fsetpos函数
  int fgetpos(FILE *restrict fp, fpos_t *restrict pos);
  int fsetpos(FILE *fp, const fpos_t pos);
  两个函数成功返回0,失败返回非零值
 
  fgetpos将文件位置指示器的当前值存入有pos指向的对象中。在以后调用fsetpos时,可以用此值将流重新定位到该位置。
 
六、其他
int fileno(FILE *fp); //返回与该流相关联的文件描述符  
临时文件:
  char *tmpnam(char *ptr);//返回唯一路径名的指针
 
  FILE *tmpfile(void);//成功返回文件指针,出错返回NULL
  tmpnam函数产生一个与现有文件名不同的一个有效路径名字符串。每次调用都产生一个不同的路径名。最多调用TMP_MAX次。
 
  若ptr是NULL,则所产生的路径名存放在一个静态区中,指向该静态区的指针作为函数值返回,下一次调用tmpnam时,会重写该静态区(这意味着,如果我们调用此函数多次,而且想保存路径名,则我们应当保存该路径名的副本,而不是指针的副本)。若ptr不是NULL,则认为它指向长度至少时L_tmpnam个字符的数组(常量L_tmpnam定义在头文件stdio.h中),所产生的路径名存放在该数组中,ptr也作为函数值返回。
  tmpfile创建一个临时二进制文件(类型wb+),在关闭文件或者程序结束时将自动删除这种文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值