C标准头文件<stdio.h>
是很多人学C语言接触的第一个头文件,顾名思义,stdio就是"标准输入输出",其中声明了一组关于输入输出的类型,宏和函数,其中就包括了打印著名的"hello,world!"的printf(),但是,这并不意味着这个头文件就很简单,相反,这个头文件是C标准库里唯二包罗万象的一个库(另一个是)。好,让我们从头审视一下这个头文件
概念
文件描述符file descriptor
似于Windows系统的文件句柄,Unix/Linux系统用来描述文件的一个正整数,OS负责分发文件描述符给程序员,并把关于这个文件细节的控制信息存储在自己的专用内存中,这些信息由OS维护,不需要程序员费心思。
文本VS二进制
在ANSI C编程可以指定文件的打开方式是按照"二进制"还是"文本"方式,如果在Unix系统这种不区分"文本"和"二进制"的系统中,可以省略这种指定,但是毕竟很多OS还是对这两种文件类型加以区分的,所以最好还是进行明确的指定以便实现可移植性。
流stream
ANSI C将对文件读写看作是数据的流出和流入,而隐藏了文件物理存储介质的不同,即不论这个文件是存储的磁盘,内存,FLASH还是其他地方,在程序员看来都只是一个文件,而对一个文件的处理都是数据的流入和流出。打开一个文件会把一个物理介质上的文件连接到流的一端。通过流来对实际的文件进行读写,关闭一个文件会把一个物理介质上的文件和流断开。
ANSI C规定了两种流——文本流和二进制流,前者将数据看作字符,即201609是6个字符'2','0','1','6','0','9',占6byte,而在二进制流中,这就是int,占4byte。此外,文本流也会将'\n'转换成'回车CR'和'换行LR'两个字符,而二进制流不会。从这两个角度看,二进制流的流动速度比文本流更快,也更省存储空间
数据类型
size_t
FILE
FILE是ANSIC中用来保存文件信息的一个结构体,使用ANSI C编程时打开一个文件就是得到的就是一个FILE*(文件指针),如果是使用UNix/Linux系统下的编译器,那么任何通过对FILE*对文件的操作底层都是使用文件描述符来实现的,当然其他平台的具体实现还可能不一样
//gcc 4.9.2中对FILE类型的声明
typedef struct _IO_FILE FILE;
struct _IO_FILE {
int _flags;
char* _IO_read_ptr;
char* _IO_read_end;
char* _IO_read_base;
char* _IO_write_base;
char* _IO_write_ptr;
char* _IO_write_end;
char* _IO_buf_base;
char* _IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
# 293 "/usr/include/libio.h" 3 4
__off64_t _offset;
# 302 "/usr/include/libio.h" 3 4
void *__pad1;
void *__pad2;
void *__pad3;
void *__pad4;
size_t __pad5;
int _mode;
char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
};
typedef struct _IO_FILE _IO_FILE;
fpos_t
fpos_t可以唯一指定文件中的每个位置所需的所有信息,实际上是一个整型变量,用来记录当前读写位置距离文件开头的byte数,很多文件读写函数在读写一次后都会改写这个变量的值
宏
NULL
_IOFBF, _IOLBF, _IONBF
这三个宏展开为具有不同值的常量表达式,是个作为函数setvbuf的第三个arg
BUFSIZ
展开为一个整型常量表达式,只setbuf()缓冲池的大小
EOF
End of File,展开为一个负的整型常量表达式,表示一个流结束了
FOPEN_MAX
展开为一个整型常量表达式,表示当前环境下可以同时打开文件数目的最大数目
FILENAME_MAX
展开为一个整型常量表达式,表示用来保存文件名的char数组的大小,即文件名的最大长度
L_tmpnam
展开为一个整型常量表达式,表示用来保存tmpnam()生成的临时文件名串的char数组的大小
SEEK_CUR, SEEK_END, SEEK_SET
展开为不同值的整型常量表达式,用作fseek()函数的arg
TMP_MAX
展开为一个整型常量表达式,表示tmpnam()可以声场的单独文件名的最小数目
stderr, stdin, stdout
展开为一个"FILE*"类型的表达式,分别指向标准错误流,标准输入流,标准输出流,Unix/Linux系统中这三个流默认分别是显示器,键盘,显示器
函数
文件访问
remove()
/*
功能:导致一个文件再也不能通过它的文件名filename访问,除非重新创建该文件
返回值:成功返回0,否则返回非0
*/
int remove(const char* filename);
rename()
/*
功能:把名字为oldname的文件改名为newname
返回值:
*/
int rename(const char* oldname,const char* newname);
tmpfile()
/*
功能:创建一个临时二进制文件,文件被关闭就会被移除
返回值:成功返回FILE*,否则返回void\*
FILE* tmpfile(void);
tmpnam()
//生成一个有效的文件名
char* tmpnam(char* s);
fclose()
/*
功能:将stream指向的流被清空,并且和流相关联的文件被关闭,流中任何未写出的缓冲数据都传递到环境并写入文件,任何未读的都被丢弃。
返回值:成功返回0,否则返回EOF
*/
int fclose(FILE* stream);
fflush()
/*
功能:清空stream指向的流,未写入文件的会被写入,未读的丢弃
参数:流stream
返回值:
*/
int fflush(FILE* stream);
fopen()
/*
功能:打开以串filename为名的文件,并把这个文件和一个流相连
参数:文件名字符串filename,打开方式mode如下:
r 只读
w 清空写
a 追加写
b 放在rwa之后,表示"以二进制方式"
+ 放在rwa之后,表示"文件不存在就创建"
返回值:成功返回FILE*,失败返回void*
*/
FILE* fopen(const char* filename,const char* mode);
freopen()
/*
功能:打开路径为filename指向的串文件,并把这个文件和流stream相连
返回值:成功返回stream的值,否则返回void*
*/
FILE* freopen(const char* filename, const char* mode,FILE* stream);
setvbuf()
/*
功能:指定流stream缓冲的方式,只能在流和一个文件关联后,但还没有对流进行其他操作之前使用
参数:mode指定流缓冲的方式,_IOFBF表示完全缓冲,即缓冲区满才对文件操作,_IOLBF表示输入/输出行缓冲,即缓冲区中遇到换行就对文件进行操作,_IONBF表示输入/输出不换冲,如果buf不是void*,则可以用它指向的数组来代替setvbuf()自动分配的缓冲区,size指定了数组的大小。
返回值:成功返回0,否则返回非0;
*/
int setvbuf(FILE* stream, char* buf, int mode, size_t size);
setbuf()
/*
功能:如果buf不是void*,相当于mode为_IOFBF,size为BUFSIZd调用setvbuf(),如果哦buf是void*,相当于mode为_IONBF调用setvbuf()
返回值:无
*/
void setbuf(FILE* stream, char* buf);
格式化输出输出
fprintf()
/*
功能:按照format指向的格式控制串把输出写入stream指向的流
参数:
返回值:成功返回输出项的数目,失败返回EOF
*/
int fprintf(FILE* stream, const char* format,...);
fscanf()
/*
功能:按照format指向的格式控制串,把后面的参数作为指向接收转换后的输入的对象的指针
参数:
返回值:成功返回输入项的数目,失败返回EOF
*/
int fscanf(FILE* stream, const char* format, ...);
printf()
/*
功能:相当于fprintf(),只是把stdout作为stream
参数:
返回值:成功返回输出项的数目,否则返回负值
*/
int printf(const char* format, ...);
scanf()
/*
功能:相当于fsanf(),只是把stdin作为stream
参数:
返回值:成功返回输入项的数目,失败返回EOF
*/
int scanf(const char* formant, ...);
sprintf()
/*
功能:相当于fprintf(),只是把本来写入流stream的内容改为写入到数组s中
参数:
返回值:成功写入数组中字符的数目,不包括NUL
*/
int sprintf(char *s, const char* format, ...);
ssanf()
/*
功能:相当于fscanf(),只是把本来从流stream获取的内容改为从数组s获取
参数:
返回值:成功输入项的数目,否则返回EOF
*/
int sscanf(const char* s, const char* format, ...);
vfprintf()
/*
功能:相当于fprintf(),只是把可变参数表用arg代替
参数:
返回值:成功返回输出项的数目,否则返回一个负数
*/
int vfprintf(FILE* stream, const char* format, va_list arg);
vprintf()
/*
功能:相当于printf(),只是把可变参数表用arg代替
参数:
返回值:成功返回输出项的数目,否则返回一个负数
*/
int vprintf(const char* format, va_list arg);
vsprintf()
/*
功能:相当于sprintf(),只是把可变参数用arg代替
参数:
返回值:成功返回输出项的数目,否则返回一个负数
*/
int vsprintf(char* s, const char* format, va_list arg);
字符输出输出
fgetc()
/*
功能:从stream指向的输入流中读取下一个字符,并把它由unsigned char转换为int
参数:
返回值:成功返回读取到的字符,否则返回EOF
*/
int fgetc(FILE* stream);
fgets()
/*
功能:从stream指向的流中读取字符,读取字符的数目最多为n-1,因为至少还要给NUL留位置,然后将字符写入到数组s中,如果敲入"123回车"存储的是"123\0",这个函数会自动把输入的'\n'变成'\0',这点和scanf()不同
参数:
返回值:
*/
char* fgets(char* s, int n, FILE* stream);
fputc()
/*
功能:把c字符写入到stream指向的输出流中的文件定位符指定的位置,并将位置指针移动一个
参数:
返回值:
*/
int fputc(int c, FILE* stream);
fputs()
/*
功能:把s串的有效字符写入stream
参数:
返回值:成功返回一个非负值,否则返回EOF
*/
int fputs(const char* s, FILE* stream);
getc()
/*
功能:相当于fgetc(),只是如果getc()作为一个宏实现时,可能会对stream进行多次进算,所以它的参数不能是有副作用的表达式
参数:
返回值:
*/
int getc(FILE* stream);
getchar()
/*
功能:相当于fgetc(),只是从stream获取改为从stdin获取
参数:
返回值:
*/
int getchar(void);
gets()
/*
功能:有的资料说相当于fgets(),只是从stream获取改为从stdin获取,直到遇到一个换行符,其实gets和fgets最大的区别就是不回进行输入字符数目的限制,一旦用户输入的字符个数超过了接收buf的大小,就可能引发错误,所以不建议使用这个函数
参数:
返回值:
*/
char* gets(char* s);
putc()
/*
功能:相当于fputc(),只是如果putc()作为一个宏实现时,可能会对stream进行多次晕眩,所以它的参数不能是有副作用的表达式
参数:
返回值:
*/
int putc(int c, FILE* stream);
putchar()
/*
功能:相当于fputc(),只是输出到stream改为输出到stdout
参数:
返回值:
*/
int putchar(int c);
puts()
/*
功能:相当于fputs(),只是输出到stream改为输出到stdout
参数:
返回值:
*/
int puts(const char* s);
ungetc()
/*
功能:把c字符退回到stream
参数:
返回值:
*/
int ungetc(int c, FILE* stream);
直接输入输出
fread()
/*
功能:从stream中读取最多nmemb个元素到ptr指向的数组中
参数:
返回值:成功返回读取的元素的个数
*/
size_t fread(void *ptr, size_t size, size_t nmemb, FILE* stream);
fwrite()
/*
功能:从ptr指向的数组中读取最多nmemb个元素并将其写到stream中
参数:
返回值:
*/
size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
文件定位函数
fgetpos()
/*
功能:把stream中的定位符的当前值存储到pos指向的对象中
参数:
返回值:
*/
int fgetpos(FILE* stream, fpos_t* pos);
fseek()
/*
功能:为stream设置文件定位符
参数:offset表示以whence为基准的偏移量,whence有三种值:SEEK_SET表示以文件开头为基准,SEEK_CUR表示以当前文件定位符位置为基准,SEEK_END表示以文件结尾为基准
返回值:成功返回0,否则返回非0
*/
int fseek(FILE* stream, long int offset, int whence);
fsetpos()
/*
功能:根据pos指向的对象的值来设置stream中定位符的位置
参数:
返回值:成功返回0,否则返回非0,并设置errno
*/
int fsetpos(FILE* stream, const fpos_t* pos);
ftell()
/*
功能:获得stream定位符的当前值
参数:
返回值:返回文件定位符当前值,否则返回-1L,并设置errno
*/
long int ftell(FILE* stream);
rewind()
/*
功能:把stream的文件定位符设置在文件的开始位置,等价于(void) fseek(stram, 0L,SEEK_SET)
参数:
返回值:
*/
void rewind(FILE* stream);
错误处理
clearerr()
/*
功能:清空stream指向的流文件结束符和错误指示符
参数:
返回值:
*/
void clearerr(FILE* stream);
feof()
/*
功能:测试stream的文件结束符
参数:
返回值:如果stream设置了文件结束符返回一个非0
*/
int feof(FILE* stream);
ferror()
/*
功能:测试stream指向的流的错误提示符
参数:
返回值:如果stream设置了错误提示符返回非0
*/
int ferror(FILE* stream);
perror()
/*
功能:把errno转换成一个human-readable的信息
参数:
返回值:
*/
void perror(const char* s);
C标准头文件<stdio.h>的更多相关文章
- C标准头文件<math.h>
定义域错误可以理解为超出了函数的适用范围,如果发生了定义域错误,设errno为EDOM 如果结果不能表示为double值,则发生值域错误,如果结果上溢,则函数返回HUGE_VAL的值,设errno为E ...
- C标准头文件<assert.h>
<assert.h>定义了两个用来调试程序的宏: assert和NDEBUG,assert用来判断表达式是否为真,如果为真继续执行,如果为假,向stderr输出一条错误消息,并调用< ...
- C标准头文件<ctype.h>
主要包括了一些字符识别和转换函数 字符判断 isalnum() //函数原型 #include<ctype.h> int isalum(int c); 功能:如果输入的字符是字母(alph ...
- C标准头文件<signal.h>
信号即异常,或者理解为中断,一个进程接收到一个信号,如果没有处理机制,就会按照默认的处理方式进行处理,而默认的处理方式通常是终止当前进程或忽略该信号.当然,程序也可以编写相应的处理信号的函数,一旦接收 ...
- C标准头文件<errno.h>
声明了错误处理相关的宏 errno errno即error number,在程序启动时被设为0,当某个库函数运行出现错误的时候,会将相应的能表达错误类型的数字赋值给这个左值,这些数字往往有相应的宏来表 ...
- C标准头文件<string.h>
里面主要包含了一些与字符串关联的函数的声明,这些函数有如下的命名规则: 以"mem"开头的函数操作任意的字符序列 以"strn"开头的函数操作非空字符序列 以& ...
- C标准头文件<stdlib.h>
是个大杂烩,里面声明了从动态内存分配到常用算法等各种函数和宏 #数据类型 **size_t** **wchar_t** **div_t**是一个结构体类型,也是div()返回的类型 **ldiv_t* ...
- 头文件string.h,cstring与string
string.h string.h是一个C标准头文件,所有的C标准头文件都形如name.h的形式,通过#include <string.h>可以导入此头文件.之后我们就可以在程序中使用st ...
- c标准头文件
好多C语言库函数参考还是用的TC的库函数参考,因此特地把现在C语言(C99)标准库函数的24个头文件列表如下:assert.h types.h(C99) signal.h stdlib.h c ...
随机推荐
- 利用Hexo搭建个人博客-博客发布篇
通过 <利用Hexo搭建个人博客-环境搭建篇> 以及 <利用Hexo搭建个人博客-博客初始化篇>,我们了解到了利用Hexo搭建个人博客需要的环境以及配置,下面这篇文章将会介绍如 ...
- Node.js开发者最常范的10个错误
目录 前言 1 不使用开发工具 1.1 自动重启工具 1.2 浏览器自动刷新工具 2 阻塞event loop 3 频繁调用回调函数 4 圣诞树结构的回调(回调的地狱) 5 创建一个大而完整的应用程序 ...
- SQLite帮助类SQlitehelper 实现对SQLite数据的增删改查
public class SQLiteHelper { public const string sConn = "Data Source=" + @"path" ...
- G2 2.0 更灵活、更强大、更完备的可视化引擎!
概述 G2作为一款技术产品,自诞生以来,服务于广大的Web工程师群体和一部分数据分析师.一直来,G2 因其易用的语法和扎实的可视化理论基础,广受使用者好评.G2 1.x 的可视化能力已经非常强大,使用 ...
- 看看国外的javascript题目,你能全部做对吗?
叶小钗 的博客最近都在讨论面试题目 正好以前也看过一篇,就借花献佛拿出来分享一下 http://perfectionkills.com/javascript-quiz/ 附带了自己的理解,答案有争议的 ...
- WPF DatePicker只显示年和月 修改:可以只显示年
最近的项目,查询时只需要年和月,不需要日,因此需要对原有的DatePicker进行修改,查询了网上的内容,最终从一篇帖子里看到了添加附加属性的方法,地址是http://stackoverflow.co ...
- C指针(二)
原文链接:http://www.orlion.ga/924/ 一.指针与const限定符 const限定符与指针结合起来常见的情况有一下几种: const int *a; int const *a; ...
- 关于SubSonic3.0插件更新字符串过长引发的System.Data.SqlClient.SqlException的异常修复
最近公司客服提交了个BUG,说是更新产品详细信息时,有的可以有的更新不了,前段时间一直没空所以暂时放下,刚才又出现这个问题,所以马上处理了一下. 打开项目解决方案,进入DEBUG模式,拿到操作的数据提 ...
- 【记录】GitHub/TortoiseGit 修改邮箱/提交者
我使用 Git 客户端工具是 TortoiseGit,在提交更新的时候,不知何时起会出现下面这种情况: 正常提交作者信息显示应该是: 本来也没怎么注意,但是在提交历史中,记录就不显示出来了,也就是在首 ...
- 小菜学习编程-Winform系列(初学者)
前言 记得上次写<小菜的程序员道路(二)>,这篇文章的时候说过,要把工作以来整理的编程知识分享给大家,因为这半年来的工作实在是忙,现在也在忙着公司产品上线,但是答应的一定要实现,大家看我上 ...