ANSIC C 文件管理

一、根据数据的存储方式,文件可为分二进制文件和文本文件:

1、文本文件:ASCLL文件,每个字节存放一个ASCLL码字符,其存储量大,速度慢,便于对字符操作;

2、二进制文件:数据按其在内存中存储形式原样存放,其存储容量小,速度快,便于存放中间结果;

 

二、根据应用程序对文件的访问方式,即是否存在缓冲区。

1、缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区;如ANSI标准的I/O函数

2、非缓冲文件系统:低级文件系统,由程序为每个文件设定缓冲区。 如POSIX标准的系统调用I/O函数

非缓冲文件系统损耗一定的CPU时间,频繁的磁盘访问对程序的执行效率将造成很大的影响。

三、缓冲区类型

1.全缓冲:要求填满整个缓冲区后才进行I/O系统调用。磁盘文件常用次方式,第一次执行I/O操作,ANSI标准的文件管理函数调用malloc函数获得使用缓冲区,默认大小8196字节;

2.行缓冲:在输入或者输出时遇到换行符,标准I/O库执行系统调用。涉及一个终端如标准输入或者输出,即使没有 遇到换行符也执行系统调用,默认行缓冲大小158字节;

3.无缓冲:如果标准I/O函数写若干字符到不带缓冲区的流中,则相当于用write系统调用函数将这些字符写到相关联的打开文件中。如标准的出错流通常不带缓冲,以便出错信息及时的显示出来。如标准出错流stderr。

 

四、相关函数

1、void setbuf(FILE *steam, char *buf);

 说明:setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL。

2、int setvbuf(FILE *stream, char *buf, int type, unsigned size);

 参数:stream :指向流的指针

  buf : 期望缓冲区的地址;

  type : 期望缓冲区的类型:

  _IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据。

  _IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据。

  _IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区。

  size : 缓冲区内字节的数量。

3、FILE * fopen(const char * path,const char * mode);

 返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。

4、int fclose(FILE *stream);

功 能: 关闭一个流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区。

5、int fflush (FILE *_stream)

        更新缓冲区内容

6、字符读操作:每次从标准I/O调用只读流中的一个字符

     int fgetc(FILE *_stream);

     int get(FILE *_stream);

     getchar (void);  //从标准输入流中读入一个字符。

7、字符写操作:每次从标准I/O调用中只写一个字符到流中

       int fputc(int _c , FILE *_stream);  //写字符c到流stream 中

        int putc(int _c , FILE *_stream);

        putchar(int _c) ;向标准输出流中写一个字符 

8、行读出操作

       char *fgets(char *s, int n, FILE *stream);

参数:

  *s: 字符型指针,指向将存储到的数据地址。

  n: 整型数据,将从流中读取 n - 1 个字符。

  *stream: 指针数据,欲读取的流。

  功能:

  从文件指针stream中读取n-1个字符,存到以s为起始地址的空间里,直到读完一行,如果成功则返回s的指针,否则返回NULL。

9、行写入操作

       int fputs(char *str, FILE *fp);

     参数: str是字符型指针,可以是字符串常量,或者存放字符串的数组首地址。

  fp是文件型指针,通过打开文件函数fopen()获得的。

        功 能:向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回值为0;否则返回EOF(符号常量,其值为-1)。

      int puts(char *string);  //输出流到标准输出设备中

        用来向标准输出设备(屏幕)写字符串并换行,其调用方式为,puts(s);其中s为字符串字符(字符串数组名或字符串指针),送一字符串到流stdout中。

 10、块读出操作

        size_t fread(void *buffer, size_t size, size_t count, FILE *stream); 

  buffer 用于接收数据的内存地址,大小至少是 size*count 字节.

  size 单个元素的大小,单位是字节

  count 元素的个数,每个元素是size字节.

  stream 输入流

  返回值: 实际读取的元素数.如果返回值与count(不是count*size)不相同,则可能文件结尾或发生错误. 从ferror和feof获取错误信息或检测是否到达文件结尾.

        功 能: 从一个文件流中读数据,读取count个元素,每个元素size字节.如果调用成功返回count.如果调用成功则实际读取size*count字节

11、块写入操作

         size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);  //向文件写入一个数据块

  返回值:返回实际写入的数据块数目

  (1)buffer:是一个指针,对fwrite来说,是要输出数据的地址;

  (2)size:要写入内容的单字节数;

  (3)count:要进行写入size字节的数据项的个数;

  (4)stream:目标文件指针

  (5)返回实际写入的数据项个数count。

12、文件流定位

         long ftell(FILE *stream);    //返回当前文件位置,也就是说返回FILE指针当前位置。

         int fseek(FILE *stream, long offset, int fromwhere);  //修改当前读写位置

        第一个参数stream为文件指针

  第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移

  第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET

  SEEK_SET: 文件开头

  SEEK_CUR: 当前位置

  SEEK_END: 文件结尾

  其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2.

13、重置当前读写位置

          void rewind(FILE *stream);  //将文件内部的位置指针重新指向一个流(数据流/文件)的开头

 

 五、格式化输入/输出函数操作

1、int printf(const char *format,[argument]);  //将输出按指定格式放置在标准输出流stdout 上

2、int scanf( const char *format, ... );   //格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。

3、int fprintf(FILE *stream,char *format,[argument])   //输出按指定格式放置在指定的输出流上

4、int fscanf(FILE *stream, char *format,[argument...]);  //从指定的输入流中按指定的格式读取数据

5、int sprintf( char *buffer, const char *format, [ argument] … );  //格式化的数据写入某个字符串中

  buffer:char型指针,指向欲写入的字符串地址。

  format:char型指针,指向的内存里面存放了格式字符串。

  [argument]...:可选参数,可以是任何类型的数据。

 eg:连接字符串 返回值:字符串长度(strlen)

     char* who = "I";

  char* whom = "CSDN";

  sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "

6、 int sscanf(const char *buffer,const char *format,[argument ]...); //从一个字符串中读进与指定格式相符的数据.

           sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。  

          sscanf可以从字符串中取出整数、浮点数和字符串等。

        1)、常见用法。

  char buf[512] ;

  sscanf("123456 ", "%s", buf);//此处buf是数组名,它的意思是将123456以%s的形式存入buf中!

  printf("%s\n", buf);

  结果为:123456

  2). 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。

  sscanf("123456 ", "%4s", buf);

  printf("%s\n", buf);

  结果为:1234

  3). 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。

  sscanf("123456 abcdedf", "%[^ ]", buf);

  printf("%s\n", buf);

  结果为:123456

  4). 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。

  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);

  printf("%s\n", buf);

  结果为:123456abcdedf

  当输入:

  sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);

  printf("%s\n",buf);

  结果为:123456

  5). 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。

  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);

  printf("%s\n", buf);

  结果为:123456abcdedf

  6)、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中

  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);

  printf("%s\n", buf);

  结果为:12DDWDFF

  7)、给定一个字符串"hello, world",仅保留world。(注意:","之后有一空格,%s遇空格停止,加*则是忽略第一个读到的字符串)

  sscanf("hello, world", "%*s%s", buf);

  printf("%s\n", buf);

  结果为:world

  %*s表示第一个匹配到的%s被过滤掉,即hello被过滤了

  如果没有空格则结果为NULL。

  sscanf的功能很类似于正则表达式, 但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式.

 

 

 

 

 

 

你可能感兴趣的:(c,Stream,File,存储,buffer,磁盘)