:本文僅供初學者參閱,解惑linux
與程序代碼外的數據(文件)打交道,咱們使用到流(stream)這個概念,實現進程的虛擬內存與文件之間的數據交換。ios
——文件流:C標準庫提供了FILE(之因此命名爲FILE,由於linux將全部機制都視爲文件) ,FILE對象是一個包含了管理流所需的全部信息的結構,包括緩衝區信息、各類標記(如文件結束標記和錯誤標記)以及用於實際I/O的文 件描述符等。c++
——輸入流,輸入流:數據從文件傳送到內存的叫輸入流,數據從內存傳送到文件的叫輸入流。數據結構
——打開文件:FILE對象經過調用fopen函數建立的。如: FILE *fp, fp=fopen("filename","r"), 表示以只讀的方式創建與filename相關的文件流;filename爲當前目錄下的相對路徑名,r表明可讀(打開文件的模式)。 app
一:讀取函數
1:對一些有規範格式文件的讀取,可使用標準庫stdio.h下的fscanf函數,spa
函數原型爲:int fscanf(FILE * stream, const char * format, [argument...])3d
如讀取文件data.txt(數據格式相對規範)指針
代碼實現讀取:code
//test.c //文件讀取 #include<stdio.h> int main() { //1:建立文件流,文件指針名=fopen(文件名,使用文件方式)打開失敗則返回NULL; FILE *fp=fopen("./data.txt","r"); //以data.txt文件爲例 //2:檢測文件是否打開成功; if(!fp){ printf("打開失敗!\n"); return -1; //返回異常 } //3: int num; //用來儲存一個整型數據 char name[10], place[10]; //用來儲存兩個字符串數據 //抽象理解: //理解文件位置含義:其表示已打開文件當前可讀寫字符的位置,其表示爲一個到文件頭的整數; //fscanf在讀取數據時能夠這樣理解:文件被打開後,它就成了一個無序字節流(水流),其會經過一個管道,流向被讀取的一端; //瞭解fscanf後知道,其遇到空格字符(空格,製表符),換行符,就會中止,這裏的中止咱們能夠理解爲: //停下來爲文件中兩個不相關的數據塊作一個分隔的操做,恰好適應了咱們通常將空字符(包括換行符)做爲兩個數據之間的分隔的行爲; //咱們只需理解管道的兩端 //流進管道的一端的位置,就是文件的位置,表示已被讀到的位置。 //流出管道一端,就是進程用來讀取數據的一端,其能夠對管道中已經作區分的數據進行讀取。 //4:讀取: fscanf(fp,"%d%s%s",&num, name,place); //fscanf對流的格式化讀取。 //注1:fscanf(fp,"%da%s%s",&num,name,place); 能夠實現對數據:1a小剛 河南;的準確讀取,表示兩個數據之間以a爲界。 //注2:由於流是指針的性質,因此函數是將各數據塊的首地址交給對應參數,因此num需進行&取地址操做, //注3:由於name,place自己已表達地址,因此不用改變; fscanf(fp,"\n"); //\n爲控制字符,此時文件的位置到了第二行的開始; //接着進行操做:fscanf(fp,"%d%s%s",&num, name,place);就能夠繼續讀取第二行 //因此咱們經常只需利用一個while語句就能夠將整個文件讀取到一個數據結構(進程)中 /* while(!feof(fp)) //feof()檢測一個文件是否結束,即到達文件尾,若結束,則返回非0值,不然返回0 { fscanf(fp,"%d%s%s\n",&num, name,place); } */ //檢測讀取結果 printf("%d %s %s\n",num, name, place); //關閉流 fclose(fp); return 0; }
程序運行結果:
2:從文件中讀取整行數據(標準庫stdio.h下的fgets)
函數原型:char *fgets(char *str, int n, FILE *stream);
其從指定的流 stream 讀取一行,並把它存儲在 str 所指向的字符串內。當讀取 (n-1) 個字符時,或者讀取到換行符時,或者到達文件末尾時,它會中止,遇到空格不中止;
例從文件中讀取一行數據:
代碼實現:
//test3.c //行讀取文件數據 #include<stdio.h> #define maxlen 30 int main() { //建立文件流 FILE *fp=fopen("./data.txt","r"); //2:檢測文件是否打開成功; if(!fp){ printf("打開失敗!\n"); return -1; //返回異常 } char str[maxlen];//緩衝區,用來儲存數據 //從文件中讀取一行數據,儲存到str開始的地址,最大長度爲maxlen,而後下次讀取從下行開始 //若是該行的數據長於maxlen-1,則只能返回一個不完整的行,並下次調用時從該處開始 fgets(str,maxlen,fp); //檢測結果 printf("%s\n",str); //關閉流 fclose(fp); return 0; }
運行結果:
二:保存
1:保存與讀取每每相關聯,保存格式決定了你讀取的方式,使用函數fprintf能夠進行指定格式的保存:
函數原型爲:int fprintf( FILE *stream, const char *format, [ argument ]...)
假設保存一我的的我的信息到文件中:
/*test2.c */ //數據保存 #include<stdio.h> int main() { //例一我的的信息 int num=1; char name[10]="小明"; char place[10]="河南"; //創建與文件的流 FILE *fp=fopen("./data.txt","w"); //2:檢測文件是否打開成功; if(!fp){ printf("打開失敗!\n"); return -1; //返回異常 } //將數據格式化輸出到指定文件流,int fprintf( FILE *stream, const char *format, [ argument ]...) //注:此函數,是將format字符串寫入到指定輸出流中,format包括空格字符,非空格字符,說明符之中的一個或多個。如:fprintf(fp," "); 就是將空格輸入到流中。 //可理解爲進程藉助流將數據打印(fprintf)到了文件中; //將我的信息,寫入指定流中,數據間以一個空格分隔,最後還寫入換行符(控制字符)。 fprintf(fp,"%d %s %s\n",num, name,place); //因此經常只要利用一個while語句就能夠將講一個表(鏈表,順序表)按指定行格式寫入輸出流中 /* while(!feof(fp)) //feof()檢測一個文件是否結束,即到達文件尾,若結束,則返回非0值,不然返回0 { fprintf(fp,"%d %s %s\n",num, name,place); } */ //關閉流 fclose(fp); return 0; }
運行結果:
2:寫一個字符串到流中(fputs),函數原型:int fputs(const char *str, FILE *stream);
例:
//test4.c //保存字符串 #include<stdio.h> int main() { //1:建立文件流,文件指針名=fopen(文件名,使用文件方式)打開失敗則返回NULL; FILE *fp=fopen("./data.txt","a"); //以data.txt文件爲例,a表示追加 //2:檢測文件是否打開成功; if(!fp){ printf("打開失敗!\n"); return -1; //返回異常 } //string char string[20]="Facing the world"; //write string to the fstream fputs(string,fp); //關閉流 fclose(fp); return 0; }
運行結果:
淺談c++:
在c++中咱們可使用操做符<<, >>來進行流的讀寫操做,更加的方便和易於理解;
具體參考下列實例:
1:讀取所示數據:
代碼實現:
//c++文件讀取 #include<iostream> //輸入輸出流 #include<fstream> //文件流 //using namespace std; //若使用該聲明,則能夠不用在使用的每一個標準庫的成員前加std:: int main() { //序號,年齡,年; int num, age, year; //姓名,地址 char name[20], place[20]; //c++的文件流,ifstream爲輸入文件流 std::ifstream fp; //open爲ifstream的成員函數,功能爲打開文件,並將它與流關聯 fp.open("./data.txt",std::ios::in); //ios::in表示讀流的方式,表示打開模式。 //成員函數is_open檢查流是否有關聯文件,即打開成功與否,成功返回true,失敗返回false if(!fp.is_open()){ std::cout<<"打開文件失敗!!\n"; return 1; // 返回異常; } //讀取數據 fp>>num>>year>>age>>name>>place; //使用操做符>>,將數據傳輸到對應的變量中 //檢測 std::cout<<num<<":"<<name<<",age:"<<age<<",year:"<<year<<",live in:"<<place<<"\n"; //cout至關於printf //關閉流 fp.close(); return 0; }
運行結果:
2:往文件保存數據:
實例:保存一我的的具體信息到文件data.txt中
代碼實現:
//c++數據保存 #include<iostream> //輸入輸出流 #include<fstream> //文件流 //using namespace std; //若使用該聲明,則能夠不用在使用的每一個標準庫的成員前加std:: int main() { //序號,年齡,年; int num=3; int age=20; int year=1993; //姓名,地址 char name[20]="小龍"; char place[20]="廣元"; //c++的文件流,ofstream爲輸出文件流 std::ofstream fp; //open爲ofstream的成員函數,功能爲打開文件,並將它與流關聯 fp.open("./data.txt",std::ios::app); //ios::app表示每次寫入是都追加到流尾,表示打開模式。 //成員函數is_open檢查流是否有關聯文件,即打開成功與否,成功返回true,失敗返回false if(!fp.is_open()){ std::cout<<"打開文件失敗!!\n"; return 1; // 返回異常; } //讀取數據 fp<<num<<" "<<year<<" "<<age<<" "<<name<<" "<<place<<"\n"; //使用操做符<<,將各數據傳輸到流所關聯的文件中 //關閉流 fp.close(); return 0; }
運行結果: