C/C++程序從文本文件中讀取(保存)數據

:本文僅供初學者參閱,解惑linux

 

  • 在C程序中:

與程序代碼外的數據(文件)打交道,咱們使用到流(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;
}

運行結果:

相關文章
相關標籤/搜索