在第三章中,全部IO函数都是围绕文件描述符展开,文件描述符用于后续IO操做。因为文件描述符相关的操做是不带缓冲的IO,须要操做者本人指定缓冲区分配、IO长度等,对设备环境要求必定的了解。数组
本章引入文件流概念,IO库将处理不少底层IO细节。安全
提供缓冲的目的是尽可能减小read和write的调用次数。标准IO提供了如下3种缓冲:函数
在填满标准IO缓冲区后再进行实际IO操做,标准IO函数一般使用malloc获取使用的缓冲区spa
在输入和输出中遇到换行符时,标准IO才执行IO操做。对于行缓冲有2个限制指针
标准库不对字符进行缓冲存储,标准错误流一般是不带缓冲的,这样就能够尽快将信息显示出来rest
可使用setbuf函数打开或者关闭缓冲机制,为了带缓冲进行IO,参数buf必须指向一个长度为BUFSIZE的缓冲区,头文件stdio.h。成功返回-,出错返回-1。code
1 /* If BUF is NULL, make STREAM unbuffered. 2 Else make it use buffer BUF, of size BUFSIZ. */ 3 extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; 4 5 /* Make STREAM use buffering mode MODE. 6 If BUF is not NULL, use N bytes of it for buffering; 7 else allocate an internal buffer N bytes long. */ 8 extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, int __modes, size_t __n) __THROW;
setvbuf的mode参数能够精确说明缓冲类型,mode参数实现为:orm
_IOFBF 全缓冲,_IOLBF 行缓冲,_IONBF 不带缓冲。对象
可使用fopen等函数打开一个IO流,头文件stdio.h。成功返回文件指针,出错返回NULL。blog
1 /* Open a file and create a new stream for it. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern FILE *fopen (const char *__restrict __filename, 6 const char *__restrict __modes) __wur; 7 /* Open a file, replacing an existing stream with it. 8 9 This function is a possible cancellation point and therefore not 10 marked with __THROW. */ 11 extern FILE *freopen (const char *__restrict __filename, 12 const char *__restrict __modes, 13 FILE *__restrict __stream) __wur;
fopen函数打开路径为__filename的文件
freopen函数在一个指定的流上打开文件。若是该流已经打开,则先关闭该流。若是该流已经定向,则使用freopen清除该定向。
mode参数指定对该IO流的读写方式,ISO C规定mode参数能够右15种取值。
使用fclose能够关闭一个打开的流,头文件stdio.h。成功返回0,失败返回-1。
1 /* Close STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern int fclose (FILE *__stream); 6 /* Flush STREAM, or all streams if STREAM is NULL.
下面函数用于一次读取一个字符,头文件stdio.h。成功返回下一个字符,达到文件尾或者出错,返回EOF(定义在libio.h)。
1 /* Read a character from STREAM. 2 3 These functions are possible cancellation points and therefore not 4 marked with __THROW. */ 5 extern int fgetc (FILE *__stream); 6 extern int getc (FILE *__stream); 7 8 /* Read a character from stdin. 9 10 This function is a possible cancellation point and therefore not 11 marked with __THROW. */ 12 extern int getchar (void); 13 14 #ifndef EOF 15 # define EOF (-1) 16 #endif
前两个函数的区别是,getc能够被实现为宏,而fgetc不能实现为宏?
getchar等价于geic (stdin)。
这三个函数达到文件尾或者出错,都返回EOF。为区别文件尾或者出错,须要调用如下函数进行判断,头文件stdio.h。成功返回非0,失败返回0。能够做为bool型判断。
1 /* Clear the error and EOF indicators for STREAM. */ 2 extern void clearerr (FILE *__stream) __THROW; 3 /* Return the EOF indicator for STREAM. */ 4 extern int feof (FILE *__stream) __THROW __wur; 5 /* Return the error indicator for STREAM. */ 6 extern int ferror (FILE *__stream) __THROW __wur;
调用clearerr能够清除这两个标志。
也可使用ubgetc将字符再写回流缓冲区,头文件stdio.h。成功返回c,失败返回EOF。
1 /* Push a character back onto the input buffer of STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern int ungetc (int __c, FILE *__stream);
对应的写缓冲区函数为:
1 /* Write a character to STREAM. 2 3 These functions are possible cancellation points and therefore not 4 marked with __THROW. 5 6 These functions is a possible cancellation point and therefore not 7 marked with __THROW. */ 8 extern int fputc (int __c, FILE *__stream); 9 extern int putc (int __c, FILE *__stream); 10 11 /* Write a character to stdout. 12 13 This function is a possible cancellation point and therefore not 14 marked with __THROW. */ 15 extern int putchar (int __c);
下面两个函数每次读写输出一行,头文件stdio.h。成功返回buf,到达文件尾或者出错,返回NULL。
1 /* Get a newline-terminated string of finite length from STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) 6 __wur; 7 8 /* Get a newline-terminated string from stdin, removing the newline. 9 10 This function is impossible to use safely. It has been officially 11 removed from ISO C11 and ISO C++14, and we have also removed it 12 from the _GNU_SOURCE feature list. It remains available when 13 explicitly using an old ISO C, Unix, or POSIX standard. 14 15 This function is a possible cancellation point and therefore not 16 marked with __THROW. */ 17 extern char *gets (char *__s) __wur __attribute_deprecated__; 18 19 20 /* Write a string to STREAM. 21 22 This function is a possible cancellation point and therefore not 23 marked with __THROW. */ 24 extern int fputs (const char *__restrict __s, FILE *__restrict __stream); 25 26 /* Write a string, followed by a newline, to stdout. 27 28 This function is a possible cancellation point and therefore not 29 marked with __THROW. */ 30 extern int puts (const char *__s);
注意如下两点:
上一节的流IO没法解决如下问题:当读取的数据是结构化数据(非字符串,可能读取到NULL,0),流IO将会截断。
为解决该问题,须要引入二进制IO函数fread和fwrite,头文件stdio.h。函数返回读或写的对象数。
1 /* Read chunks of generic data from STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern size_t fread (void *__restrict __ptr, size_t __size, 6 size_t __n, FILE *__restrict __stream) __wur; 7 /* Write chunks of generic data to STREAM. 8 9 This function is a possible cancellation point and therefore not 10 marked with __THROW. */ 11 extern size_t fwrite (const void *__restrict __ptr, size_t __size, 12 size_t __n, FILE *__restrict __s);
可以使用ftell获取当前文件访问偏移量、fseek对文件访问进行偏移、rewind将流设置到起始位置。
1 /* Seek to a certain position on STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern int fseek (FILE *__stream, long int __off, int __whence); 6 /* Return the current position of STREAM. 7 8 This function is a possible cancellation point and therefore not 9 marked with __THROW. */ 10 extern long int ftell (FILE *__stream) __wur; 11 /* Rewind to the beginning of STREAM. 12 13 This function is a possible cancellation point and therefore not 14 marked with __THROW. */ 15 extern void rewind (FILE *__stream);
fseek的第三个参数whence与fseek的参数相同:
SEEK_SET指定从文件起始位置开始,SEEK_CUR指定从当前位置开始,SEEK_END指定从文件末尾
格式化输出由5个printf函数处理,头文件stdio.h。成功返回字符数,失败返回负值。
1 /* Write formatted output to stdout. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern int printf (const char *__restrict __format, ...); 6 7 /* Write formatted output to STREAM. 8 9 This function is a possible cancellation point and therefore not 10 marked with __THROW. */ 11 extern int fprintf (FILE *__restrict __stream, 12 const char *__restrict __format, ...); 13 14 extern int dprintf (int __fd, const char *__restrict __fmt, ...) 15 __attribute__ ((__format__ (__printf__, 2, 3))); 16 17 /* Write formatted output to S. */ 18 extern int sprintf (char *__restrict __s, 19 const char *__restrict __format, ...) __THROWNL; 20 21 /* Maximum chars of output to write in MAXLEN. */ 22 extern int snprintf (char *__restrict __s, size_t __maxlen, 23 const char *__restrict __format, ...) 24 __THROWNL __attribute__ ((__format__ (__printf__, 3, 4)));
printf将格式化数据写到标准输出
fprintf将格式化数据写到指定的流
dprintf写到指定的文件描述符
sprintf写到数组S
snprintf是sprintf的安全版本,指定了缓冲区的长度,防止缓冲区溢出
格式化输入由3个scanf函数处理,头文件stdio.h。成功返回输入的参数,失败或者到达文件末尾,返回EOF。
1 /* Read formatted input from STREAM. 2 3 This function is a possible cancellation point and therefore not 4 marked with __THROW. */ 5 extern int fscanf (FILE *__restrict __stream, 6 const char *__restrict __format, ...) __wur; 7 /* Read formatted input from stdin. 8 9 This function is a possible cancellation point and therefore not 10 marked with __THROW. */ 11 extern int scanf (const char *__restrict __format, ...) __wur; 12 /* Read formatted input from S. */ 13 extern int sscanf (const char *__restrict __s, 14 const char *__restrict __format, ...) __THROW;
可使用tmpnam或者tmpfile建立临时二进制文件。头文件stdio.h。
1 /* Generate a temporary filename. */ 2 extern char *tmpnam (char *__s) __THROW __wur; 3 4 /* Create a temporary file and open it read/write. 5 6 This function is a possible cancellation point and therefore not 7 marked with __THROW. */ 8 extern FILE *tmpfile (void) __wur;
tmpnam生成一个和现有文件名不一样的有效路径字符串,最多调用TMP_MAX次,定义在stdio.h。返回指向惟一路径名的指针。若是输入为NULL,则路径名存放在静态区;若是不是NULL,则应该指向长度为L_tmpnam个字符的数组。
tmpfile建立一个临时二进制文件,在关闭该文件或者程序结束时将自动删除该文件。可使用tmpfile建立一个临时文件,而后当即unlink。
1 /* Create a new stream that refers to a memory buffer. */ 2 extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) 3 __THROW __wur; 4 5 /* Open a stream that writes into a malloc'd buffer that is expanded as 6 necessary. *BUFLOC and *SIZELOC are updated with the buffer's location 7 and the number of characters written on fflush or fclose. */ 8 extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW __wur;