c++ 讀取數值檔案到數組中

來源:互聯網
上載者:User

  做資料處理時經常會用讀這樣的文字檔:

1,10,1,11,1,13,1,12,1,1,9
2,11,2,13,2,10,2,12,2,1,9
3,12,3,11,3,13,3,10,3,1,9
4,10,4,11,4,1,4,13,4,12,9
4,1,4,13,4,12,4,11,4,10,9
1,2,1,4,1,5,1,3,1,6,8
1,9,1,12,1,10,1,11,1,13,8
2,1,2,2,2,3,2,4,2,5,8
3,5,3,6,3,9,3,7,3,8,8
4,1,4,4,4,2,4,3,4,5,8 

  有時候每一行的資料個數也不是確定的,但我們想按行儲存在數組或vector(list)中,這麼久以來用習慣了java的readLine()和split(","),突然用c++,感覺到寸步難行,於是自己寫了一個函數,用c++讀取數值檔案。

/**讀取絕對路徑為filePath的檔案,檔案中每行中的數值以tag字元分開*返回vector<vector<string>>格式的資料*/vector<vector<string>> readFile(char tag,string filePath){    ifstream fileReader;    fileReader.open(filePath,ios::in);//以唯讀方式開啟    vector<vector<string>> data;//以2維向量的形勢保持整個檔案    while(!fileReader.eof()){//未到檔案末尾            string linestring;        getline(fileReader,linestring);//讀取一行        vector<string> line = split(linestring,tag);//分割每行,並放在line向量中            data.push_back(line);    }        return data;    }
readFile()函數讀取檔案,其中調用了一個split()函數,用於將一個string類型的字串分割為字串向量,實現如下:
/**對字串inputString按tag字元分割*返回vector<string>格式的一維向量*/vector<string> split(string inputString,char tag){    int length = inputString.length();    int start=0;//數值起始下標    vector<string> line;    for(int i=0;i<length;i++){        if(inputString[i] == tag){//遇到tag字元            string sub = inputString.substr(start,i-start);    //取inputString[start]-inputString[i]子串            line.push_back(sub);//壓入向量中            start =  i+1;                    }else if(i==length-1){            string sub = inputString.substr(start,i-start+1);//最後一個字元沒有標點,需單獨處理            line.push_back(sub);//壓入向量中        }    }    return line;}

  調用readFile()函數就可以將檔案以vector<vector<string>>類型讀入記憶體。但既然是數值,我們肯定要進行計算,字串數組對我們還是沒有,需要轉化為數實值型別vector<vector<int或double或float>>,這裡寫了一個轉行函數:

/**將inputString轉化成數值型,利用模板,實現複用*/template <typename T>void transToNum(string inputString,T *result){        const char *p = inputString.c_str();    char * type = getType(*result);    if(type== "int")        *result =  atoi(p);    else if(type== "double")        *result =   atof(p);    else if(type== "float")        *result =   atof(p);}

這裡利用模板實現了複用,為了能在運行時知道變數的值,c++裡面沒有getClass(),所有只有自己寫了,這裡寫了一個getType()函數:

char * getType(int x){//返回整數類型        return "int";    }char * getType(double x){//返回double類型        return "double";}char * getType(float x){//返回float類型        return "float";}

這樣最終能得到vector<vector<int或double或float>>類型的資料,進行你想要的處理。

以下測試部分和完整代碼:

#include <iostream>#include <vector>#include <fstream>#include <string>#include <ctime>using namespace std;vector<vector<string>> readFile(char tag,string filePath);vector<string> split(string inputString,char tag);template <typename T>void transToNum(string inputString,T *result);/**讀取絕對路徑為filePath的檔案,檔案中每行中的數值以tag字元分開*返回vector<vector<string>>格式的資料*/vector<vector<string>> readFile(char tag,string filePath){    ifstream fileReader;    fileReader.open(filePath,ios::in);//以唯讀方式開啟    vector<vector<string>> data;//以2維向量的形勢保持整個檔案    while(!fileReader.eof()){//未到檔案末尾            string linestring;        getline(fileReader,linestring);//讀取一行        vector<string> line = split(linestring,tag);//分割每行,並放在line向量中            data.push_back(line);    }        return data;    }/**對字串inputString按tag字元分割*返回vector<string>格式的一維向量*/vector<string> split(string inputString,char tag){    int length = inputString.length();    int start=0;//數值起始下標    vector<string> line;    for(int i=0;i<length;i++){        if(inputString[i] == tag){//遇到tag字元            string sub = inputString.substr(start,i-start);    //取inputString[start]-inputString[i]子串            line.push_back(sub);//壓入向量中            start =  i+1;                    }else if(i==length-1){            string sub = inputString.substr(start,i-start+1);//最後一個字元沒有標點,需單獨處理            line.push_back(sub);//壓入向量中        }    }    return line;}char * getType(int x){//返回整數類型        return "int";    }char * getType(double x){//返回double類型        return "double";}char * getType(float x){//返回float類型        return "float";}/**將inputString轉化成數值型,利用模板,實現複用*/template <typename T>void transToNum(string inputString,T *result){        const char *p = inputString.c_str();    char * type = getType(*result);    if(type== "int")        *result =  atoi(p);    else if(type== "double")        *result =   atof(p);    else if(type== "float")        *result =   atof(p);}int main(){    string filePath ="E:\\學習\\機器學習\\Poker_hand\\train.data";    time_t now;    now = time(NULL);//設定開始時間    cout<<now<<endl;    vector<vector<string>> data = readFile(',',filePath);//讀檔案    now = time(NULL);//讀完時間    cout<<now<<endl;    //////////////////將讀到的vector<vector<string>>轉化為vector<vector<int>>或vector<vector<double>>///////////    vector<vector<int>> intdata;    vector<vector<string>>::iterator iter =  data.begin();    for(;iter != data.end();iter++){        vector<string> line = *iter;        vector<string>::iterator lineiter =  line.begin();        vector<int> intline;        for(;lineiter != line.end();lineiter++){            int result;            transToNum(*lineiter,&result);            intline.push_back(result);            }        intdata.push_back(intline);    }    ////////////////遍曆intdata,輸出數值化的資料////////////////////////////////////////////    vector<vector<int>>::iterator intIter =  intdata.begin();    for(;intIter != intdata.end();intIter++){        vector<int> line = *intIter;        vector<int>::iterator lineiter =  line.begin();                for(;lineiter != line.end();lineiter++){                        cout<<*lineiter<<" ";                    }                cout<<endl;    }        return 1;//main}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.