【问题标题】:Parsing data of string in vector to appropriate data type c++将向量中的字符串数据解析为适当的数据类型c++
【发布时间】:2017-03-27 16:27:02
【问题描述】:

大家好,我正在从 CSV 文件中读取数据并成功解析出数据中的所有字符,现在我需要将每列中的字符串数据转换为其适当的类型(int、double 等)。我声明了我想要的以下类型,然后从那里每个变量都应该更新为尽可能多的行,这样我就可以获取该变量并在程序中的其他地方调用它。请看下文

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
        }

【问题讨论】:

  • 你好像没问问题?
  • 我正在尝试将完全解析后的数据转换为我在上面声明的适当数据类型?
  • 你这样做有什么问题?通常对于 CSV 文件,您必须在解析文件之前决定列类型。
  • 不能根据运行时类型进行转换。您需要一个基于类型调用特定函数的模板函数。
  • int a, b, c,f ;双 d,e,g,h,i,j,k 对不起

标签: c++ c++11 c++14


【解决方案1】:

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

int c;
double c;

你也没有main()函数

由于这些错误,这可能不完全符合您的需求。假设每行包含三个ints、四个doubles、一个int,然后是两个doubles,我将声明一个“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));
    }
}

【讨论】:

  • 你的comma 输入很容易吃掉空格而不是逗号。使用ss &gt;&gt; a &gt;&gt; std::ws &gt;&gt; comma &gt;&gt; b &gt;&gt; std::ws &gt;&gt; comma &gt;&gt; ... 将是一个额外的保障。如果linedata 构造没有成功解析字符串,您可能需要设置错误状态或抛出异常。
  • 当你有 using namespace std 时,不需要使用 std::: 这会让代码看起来很丑
  • @looneytunes24 我建议不要像许多程序员那样using namespace std;。我实际上在做的事情被认为是一种好的做法。见stackoverflow.com/questions/1452721/…
猜你喜欢
  • 1970-01-01
  • 2014-05-27
  • 2012-03-04
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多