zoukankan      html  css  js  c++  java
  • c++ 读取数值文件到数组中

      做数据处理时经常会用读这样的文本文件:

    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
    }
  • 相关阅读:
    .NET连接SAP系统专题:C#如何导入内文至SAP(十一)
    又开始要忙了
    .NET连接SAP系统专题:C#调用BAPI给账户赋予权限(八)
    抉择之苦
    SAP屏幕设计器专题:下拉列表框(四)
    SAP中新建客制表流程
    SAP中使用ABAP远程连接MS Sql Server服务器
    SAP屏幕设计器专题:表格控件(六)
    .NET连接SAP系统专题:C#(NCO3)调用BAPI的一些说明(六)
    SAP屏幕设计器专题:树控件的使用(九)
  • 原文地址:https://www.cnblogs.com/fengfenggirl/p/2999696.html
Copyright © 2011-2022 走看看