本章介绍标准IO库
1. FILE对象
标准IO库一切函数基于FILE对象。FILE对象包含了管理该流的所有信息: 文件描述符,指向流缓存的指针,缓存的长度,缓存的字节数以及出错标识等
2. 标准输入,标准输出和标准出错。
对应非标准IO: STDIN_FILENO, STDOUT_FILENO,STDERR_FILENO
对于标准IO: stdin,stdout,stderr.
3. 缓存
为了尽可能减少使用read和write调用的数量,标准IO提供缓存。全缓存,行缓存和不缓存。
当且仅当不涉及交互设备的时候,他们才是全缓存的。标准出错不会是全缓存。
#include
void setbuf(FILE* fp, char* buf)
int setvbuf(FILE* fp, char* buf, int mode,size_t size); int fflush(FILE* fp) //强制刷新流
#include
FILE *fopen(const char* pathname,const char* type);
FILE *freopen(const char* pathname,const char* type,FILE* fp);
FILE *fdopen(int filedes,const char* type)
int fclose(FILE* fp);
type 为:
r,rb,w,wb,a,ab,r+,r+b,rb+,w,w+b,w。 w把文件截断为0, a定位文件到末尾。b 为二进制文件读写。
freopen 的妙用:用文件冒充stdin,stdout
#include
int main()
{
int a,b;
freopen("/tmp/in.txt","r",stdin);
freopen("/tmp/out.txt","w",stdout);
while(scanf("%d %d",&a,&b)!=EOF)
printf("%d\n",a+b);
fclose(stdin);
fclose(stdout);
return 0;
}
每次处理一个字符;每次处理一行;直接IO。
6.字符读
#include
int getc(FILE * f p) ;
int fgetc(FILE * f p) ;
int getchar(void);
成功则为下一个字符,若已处文件尾端或出错则为EOF. getc 为宏,fgetc为函数
使用 ferror 或者feof 查看读结束状态,clearerr 清除error. ugetc可以送回读出来的字符。
7.字符写
字符写跟字符读正好相反。
#include
int putc(int c, FILE * fp) ;
int fputc(int c, FILE * fp);
int putchar(int c) ;
#include
char *fgets(char * buf, int n,FILE * fp) ;
char *gets(char * buf) ; //基本不建议用,防止buf溢出。
#include
int fputs(const char * str, FILE * fp) ;
int puts(const char * str);
#include
size_t fread(void * ptr, size_t size, size_t nobj, FILE * fp) ;
size_t fwrite(const void* ptr, size_t size, size_t nobj,FILE* fp); //缺点是异构系统上二进制读写会产生问题。
二进制读写的一个简单demo:
#include
#include
struct school
{
int number;
char name[1024];
};
int main()
{
struct school southeast;
southeast.number = 4096;
memset(southeast.name, 1024,0);
strcpy(southeast.name, "southeast university");
FILE* fp = fopen("/tmp/bintest","w");
if(fwrite(&southeast, sizeof(struct school),1, fp)!=1)
{
printf("fwrite error\n");
return -1;
}
fclose(fp);
FILE* fp2 = fopen("/tmp/bintest","r");
struct school su;
if(fread(&su, sizeof(struct school),1, fp2)!=1)
{
printf("fread error error\n");
return -1;
}
printf("number =%d,name=%s\n",su.number, su.name);
}
#include
long ftell(FILE * fp) ;
返回:若成功则为当前文件位置指示,若出错则为- 1 L
int fseek(FILE * fp,long offset,int whence) ;
返回:若成功则为0,若出错则为非0
void rewind(FILE * fp) ; //使文件重新回到头
#include
int fgetpos(FILE * fp, fpos_t * pos) ;
int fsetpos(FILE * fp, const fpos_t * pos) ;
经典的几个格式化输出函数
#include
int printf(const char *format, ...);
int fprintf(FILE * fp, const char *format, ...);
int sprintf(char * buf, const char *format, ...);
int scanf(const char * format, ...);
int fscanf(FILE * fp, const char *format, ...);
int sscanf(const char * buf, const char *format, ...);
简单demo:
#include
#include
#define MAXLINE 1024
int main(int argc, char* argv[])
{
char name[L_tmpnam] , line[MAXLINE];
printf("tmp name is %s\n", tmpnam(NULL));
tmpnam(name);
printf("tmp name is %s\n", (name));
FILE* fp;
if((fp=tmpfile())==NULL)
{
printf("error");
exit(0);
}
fputs("put one line to file\n",fp);
rewind(fp);
if (fgets(line,sizeof(line),fp)==NULL)
{
printf("fgets error");
exit(0);
}
fputs(line,stdout);
exit(0);
}
~