本章介紹標準IO庫
1. FILE對象
標準IO庫一切函數基於FILE對象。FILE對象包含了管理該流的所有信息: 文件描述符,指向流緩存的指針,緩存的長度,緩存的字節數以及出錯標識等
2. 標準輸入,標準輸出和標準出錯。
對應非標準IO: STDIN_FILENO, STDOUT_FILENO,STDERR_FILENO
對於標準IO: stdin,stdout,stderr.
3. 緩存
爲了儘可能減少使用read和write調用的數量,標準IO提供緩存。全緩存,行緩存和不緩存。
當且僅當不涉及交互設備的時候,他們纔是全緩存的。標準出錯不會是全緩存。
#include <stdio.h>
void setbuf(FILE* fp, char* buf)
int setvbuf(FILE* fp, char* buf, int mode,size_t size); int fflush(FILE* fp) //強制刷新流
#include <stdio.h>
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(<span style="font-family: Arial, Helvetica, sans-serif;">FILE* fp</span>);
type 爲:
r,rb,w,wb,a,ab,r+,r+b,rb+,w,w+b,w。 w把文件截斷爲0, a定位文件到末尾。b 爲二進制文件讀寫。
freopen 的妙用:用文件冒充stdin,stdout
#include <stdio.h>
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;
}
5.讀和寫流的方式
每次處理一個字符;每次處理一行;直接IO。
6.字符讀
#include <stdio.h>
int getc(FILE * f p) ;
int fgetc(FILE * f p) ;
int getchar(void);
成功則爲下一個字符,若已處文件尾端或出錯則爲EOF. getc 爲宏,fgetc爲函數
使用 ferror 或者feof 查看讀結束狀態,clearerr 清除error. ugetc可以送回讀出來的字符。
7.字符寫
字符寫跟字符讀正好相反。
#include <stdio.h>
int putc(int c, FILE * fp) ;
int fputc(int c, FILE * fp);
int putchar(int c) ;
8. 行讀寫
#include <stdio.h>
char *fgets(char * buf, int n,FILE * fp) ;
char *gets(char * buf) ; //基本不建議用,防止buf溢出。
#include <stdio.h>
int fputs(const char * str, FILE * fp) ;
int puts(const char * str);
#include <stdio.h>
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 <stdio.h>
#include <string.h>
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);
}
10. 定位文件
#include <stdio.h>
long ftell(FILE * fp) ;
返回:若成功則爲當前文件位置指示,若出錯則爲- 1 L
int fseek(FILE * fp,long offset,int whence) ;
返回:若成功則爲0,若出錯則爲非0
void rewind(FILE * fp) ; //使文件重新回到頭
#include <stdio.h>
int fgetpos(FILE * fp, fpos_t * pos) ;
int fsetpos(FILE * fp, const fpos_t * pos) ;
11. 格式化IO
經典的幾個格式化輸出函數
#include <stdio.h>
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 <stdio.h>
#include <stdlib.h>
#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);
}
~