2017-03-26 38 views
0

hello我正在读取CSV文件中的数据,并已成功解析出数据中的所有字符,现在我需要将每列中的字符串数据转换为适当的类型(int,double等)。我有我想要的以下类型声明,然后从那里每个变量应该更新为尽可能多的行,所以我可以采取该变量并将其称为程序中的其他地方。请参阅下面解析向量中字符串的数据为适当的数据类型C++

vector<std::vector<std::string> > matrix; 
int a; 
int b; 
int c; 
double c; 
double d; 
double e; 
double f; 
int f; 
double f; 
double f; 
string line; 
ifstream file("mynumbers - Copy.csv"); 

if (!file.is_open()) 
    perror("error while opening file"); 

    getline(file, line, '\n');//get the first line of columns names out 

while (getline(file, line,'\n')) //find the endline charcater 
    { 

     vector<string> vec; 
     string linevec; 
     istringstream ss(line);//allows for parsing each line 

     while (getline(ss, linevec, ',')) 
     { 

      vec.push_back(linevec);//push the parsed data for that line into a vector 
     } 

matrix.emplace_back(vec);//push each parsed line into another vector 
     } 
+0

您似乎缺少提问? –

+0

我试图将数据完全解析后将其转换为我在上面声明的占用数据类型? – looneytunes24

+0

你有什么问题呢?通常在使用CSV文件时,必须在解析文件之前决定列类型。 –

回答

0

您可能想检查您的代码的常见错误。像这样的东西永远不会编译:

int c; 
double c; 

您还没有main()功能

由于这些错误,这可能不适合你的需求完全吻合。假设每行有三个int S,4个double S,一个int,和那么双double S,我将宣布一个“linedata”类像这样:

#include <iostream> // for std::string 
#include <string> // for std::string 
#include <sstream> // for std::istringstream 
#include <utility> // for std::forward 
#include <fstream> // for std::ifstream 
#include <vector> // for std::vector 
#include <stdexcept> // for std::runtime_error 

class linedata 
{ 
    int a; 
    int b; 
    int c; 
    double d; 
    double e; 
    double f; 
    double g; 
    int h; 
    double i; 
    double j; 

public: 

    // constructs a linedata object 
    linedata(std::string&& line) 
    { 
     std::istringstream ss(std::forward<std::string>(line)); 
     char comma; 
     ss >> a >> std::ws >> comma >> std::ws >> // std::ws discarding extra spaces 
       b >> std::ws >> comma >> std::ws >> 
       c >> std::ws >> comma >> std::ws >> 
       d >> std::ws >> comma >> std::ws >> 
       e >> std::ws >> comma >> std::ws >> 
       f >> std::ws >> comma >> std::ws >> 
       g >> std::ws >> comma >> std::ws >> 
       h >> std::ws >> comma >> std::ws >> 
       i >> std::ws >> comma >> std::ws >> 
       j; 

     // check for errors. throw if it fails to parse 
     if(ss.fail()) throw std::runtime_error("Could not parse line!"); 

     std::cout << a << '\n' << b << '\n' << c << '\n' << d << '\n' << 
        e << '\n' << f << '\n' << g << '\n' << h << '\n' << 
        i << '\n' << j << std::endl; 
    } 
}; 

然后,在main(),您可以尝试打开文件解析字符串:

int main() 
{ 
    std::vector<linedata> lines; 

    std::ifstream file("mynumbers - Copy.csv"); 
    if(! file.is_open()) 
     // personally I would not use perror because it is part of c and 
     // requires yet another header. I'd use this: 
     std::cerr << "Error occurred: " << std::strerror(errno) << std::endl; 

    std::string myline; 
    std::getline(file,myline); // the '\n' is not necessary. It gets a line. 
           // it already knows to look for '\n'. 

    while(std::getline(file,myline)) 
    { 
     lines.emplace_back(std::move(myline)); 
    } 
} 
+1

您的'逗号'输入可以很容易地使用空格而不是逗号。使用'ss >> a >> std :: ws >>逗号>> b >> std :: ws >>逗号>> ...'会是一个额外的保障。你可能想要设置一个错误状态或者抛出'linedata'构造没有成功解析字符串。 – paddy

+0

好点。我现在会更新我的答案。 –

+0

有没有必要使用std :::当你使用命名空间std这使得代码看起来很丑 – looneytunes24