對于每一個ANSI C程式而言,至少打開三個流:标準輸入(stdin)、标準輸出(stdout)、标準錯誤(stderr),他們都是一個指向FILE結構的指針。
标準輸入為:鍵盤裝置
标準輸出為:終端或螢幕。
标準庫I/O一般情況:
1. 程式必須為同時處于活動狀态的每個檔案聲明一個指針變量,其類型為: FILE* ,這個指針指向一個結構,當它處于活動狀态時由流使用。
2. 流通過fopen函數打開,打開流的時候,必須指定需要通路的檔案或者裝置已經通路的方式。fopen函數和作業系統去驗證檔案或者裝置确實存在,驗證通路方式,然後初始化FILE結構
3.根據需要對檔案進行讀取和寫入。
4.最後,fclose函數可以關閉流。關閉一個流可以防止與它相關的檔案被再次通路,保證任何存儲于緩沖區中的資料被正确的寫入檔案中。
1.FILE * fopen ( const char * filename, const char * mode );
1> r 隻讀 ,檔案必須已存在
2> w 隻寫,如果檔案不存在則建立,如果檔案已存在則把檔案長度截斷(Truncate)為0位元組再重新寫,也就是替換掉原來的檔案内容
3> a 隻能在檔案末尾追加資料,如果檔案不存在則建立
4> r+ 允許讀和寫,檔案必須已存在
5> w+ 允許讀和寫,如果檔案不存在則建立,如果檔案已存在則把檔案長度截斷為0位元組再重新寫
6> a+ 允許讀和追加資料,如果檔案不存在則建立
使用fopen打開檔案時如果出錯,fopen将傳回NULL并設定errno,必須對此進行處理:
if (fp == NULL) {
perror("fopen");
exit(1);
}
2.int fclose ( FILE * stream );//需與fopen配套使用(打開流一定要關閉)
字元I/O:
3.int getc ( FILE * stream );
4.int putc ( int character, FILE * stream );
int main()
{
FILE *fp = fopen("log.txt", "wt");
if (NULL == fp)
{
perror("fopen");
return 1;
}
//int i = 0; //将hello czf!寫入log.txt
//while (i++ < 10)
//{
// fputs("hello czf!\n", fp);
//}
//int ch; //計算檔案中的!
//size_t count = 0;
//do{
// ch = getc(fp);
// if ('!' == ch)
// {
// printf("%c : %d\n",ch, count);
// }
// count++;
//} while (ch != EOF);
//printf("end = %d\n", ch);
int ch = 'A';
while (ch <= 'Z') //将A-Z逐個寫入fp
{
putc(ch, fp);
putc('\n', fp);
ch++;
}
fclose(fp);
return 0;
}
未格式化的行I/O
char * gets ( char * str );
int puts ( const char * str )
5.char * fgets ( char * str, int num, FILE * stream );
6.int fputs ( const char * str, FILE * stream );
int main()
{
char buf[255] = {0};
while (1) //從标準輸入讀入,列印到标準輸出
{
gets(buf);
if (strcmp("quit", buf) == 0)
{
break;
}
//printf("echo:%s\n", buf);
puts(buf);
}
printf("quit!\n");
FILE *fp = fopen("myfile.txt", "w");
if (NULL == fp)
{
perror("fopen");
return 1;
}
char buf[128];
while (1) //從檔案讀到緩沖區,再從緩沖區讀到螢幕
{
fgets(buf, 10, fp);
if (feof(fp))
{
printf("end of file! quit!\n");
break;
}
fputs(buf, stdout);
fflush(stdout);
Sleep(1000);
}
char buf[128];
while (1)
{
printf("enter:");
fgets(buf, 128, stdin);
if (strncmp("quit", buf, 4) == 0)
{
break;
}
fputs(buf, fp);
}
fclose(fp);
return 0;
}
格式化的行I/O
int scanf ( const char * format, ... ); //傳回成功轉換和配置設定的字段的數量
int printf ( const char * format, ... ); //傳回值為列印的字元數,出現錯誤,列印負值 printf("%d", printf("%d",2)); 21
輸出緩存重新整理到目标位址的時機:
1.\n
2.scanf
3.exit
4.核心緩存滿
5.fflush(stdout);
7.int fscanf ( FILE * stream, const char * format, ... );
8.int fprintf ( FILE * stream, const char * format, ... );
#include <stdio.h>
#include <string.h>
int main()
{
float f;
char buf[16] = {0};
char name[16] = {0};
FILE *fp = fopen("log.txt", "w+");
if(NULL == fp)
{
perror("fopen");
return 1;
}
fprintf(fp, "%f %s", 3.14159, "PI");
rewind(fp); //将流的讀寫位置充值到最開始
fscanf(fp, "%f %s", &f, buf);
printf("%f, %s\n", f, buf);
fclose(fp);
return 0;
}
二進制I/O:
9.size_t fread ( void * ptr, size_t size, size_t count, FILE* stream ); <緩沖區名> <一個單元的大小> <要讀多少單元> <流>
10.size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); <寫出緩沖區> <單元大小> <多少個單元> <流>
#include <stdio.h>
int main()
{
char buff[] = {'A' , 'B' , 'C'};
FILE *fp = fopen("myfile.bin","wb+");
if(NULL == fp){
perror("fopen");
return 1;
}
fwrite(buff,sizeof(char),sizeof(buff),fp);
fclose(fp);
return 0;
}
11.int fseek(FILE *stream, long offset, int whence); <流> <偏移量> <偏移位置>//進行檔案寫入位置的定位
fseek的whence和offset參數共同決定了讀寫位置移動到何處,whence參數的含義如下:
SEEK_SET
從檔案開頭移動offset個位元組
SEEK_CUR
從目前位置移動offset個位元組
SEEK_END
從檔案末尾移動offset個位元組
offset可正可負,負值表示向前(向檔案開頭的方向)移動,正值表示向後(向檔案末尾的方向)移動,如果向前移動的位元組數超過了檔案開頭則出錯傳回,如果向後移動的位元組數超過了檔案末尾,再次寫入時将增大檔案尺寸,從原來的檔案末尾到fseek移動之後的讀寫位置之間的位元組都是0。
12. void rewind(FILE *stream) == int fseek(FILE *stream, 0, SEEK_SET) //回到流的最開始
13.long ftell(FILE *stream);//報告每次寫入的位置
14.int fflush(FILE *stream);
15.對比EOF和feof函數的差別?
feof()判斷檔案結尾: 二級制文本的結束标志
EOF 文本檔案的結尾标志
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
char buf[20];
FILE *fp = fopen("/bin/ls","rb");
if(NULL == fp)
{
perror("fopen");
return 1;
}
fseek(fp,0,SEEK_END); //将寫入位置移動到檔案結尾
long lsize = ftell(fp); //報告檔案為準
rewind(fp); //把光标移動到檔案開始
printf("size -> %d\n",lsize);
char *buff = (char*)malloc(sizeof(char)*lsize);
assert(buff);
ssize_t t = fread(buff,lsize, 1 ,fp); //将fp讀進buff
FILE *ofp = fopen("myls","wb+");
if(NULL == ofp){
perror("fopen");
return 1;
}
fwrite(buff,lsize, 1, ofp);
fclose(fp);
fclose(ofp);
free(buff);
// float d;
// char name[20];
// FILE *fp = fopen("czf.txt","w+");
// if(NULL == fp)
// {
// perror("fopen");
// return 1;
// }
//
// int i = 0;
// for(; i < 5; i++){
// printf("Please Enter a name:\n");
// gets(name);
// fprintf(fp, "Name %d is [%-10.20s]\n",i+1 ,name );
// }
// fprintf(fp, "%s %f\n","PI" ,3.14 );
// rewind(fp);
// fscanf(fp,"%s %f",&buff, &d);
// printf("%s %f\n",buff,d);
// fclose(fp);
return 0;
}