C++: Read CSV-file separated by ; AND \n [duplicate]

隐身守侯 提交于 2019-12-02 01:11:27

问题


Sorry if it's just pure stupidity but I'm stuck at a file reading problem via C++. This is the CSV data that I'd like to read:

5;1;0;3;3;5;5;3;3;3;3;2;3;3;0
5;1;0;3;3;5;0;3;3;3;3;2;0;0;3
5;1;1;3;3;0;0;0;0;3;5;2;3;3;3
0;3;5;5;0;2;0;3;3;0;5;1;1;0;0
0;0;3;5;5;2;0;0;0;0;5;5;1;1;0
0;0;0;0;5;2;0;0;0;0;0;5;5;1;0
;;;;;;;;;;;;;;
Code;Bezeichnung;Kosten;;;;;;;;;;;;
0;Ebene;6;;;;;;;;;;;;
1;Fluss;10; (begrenzt nutzbar);;;;;;;;;;;
2;Weg;2;;;;;;;;;;;;
3;Wald;8;;;;;;;;;;;;
4;Brücke;5;;;;;;;;;;;;
5;Felswand;12;;;;;;;;;;;;

here, I'd like to read the first values (separated by ;;;;) and store it in a 2 dimensional array. Which would not be a problem if it was seperated completely by ';'. But if use

while (getline(csvread, s, ';'))
{
[...]
}

I get information like this: {5}{1}{0}{3}{3}{5}{5}{3}{3}{3}{3}{2}{3}{3}{0\n5}{1} so it basically saves the newline and does not think of it as delimitator.

So is there an option to use getline even if you have two delimitators? Or am I completely off? I also thought about reading it line by line to a string, adding a ; to the string and rewriting it in a file in order to reuse getline using ;. But this can't seriously be the best option, right?


回答1:


you can use a splitting function like :

std::vector<std::string> split(const std::string& source, const std::string& delimiter){
    std::vector<std::string> result;

    size_t last = 0;
    size_t next = 0;

    while ((next = source.find(delimiter, last)) != std::string::npos){ 
        result.push_back(source.substr(last, next - last));
        last = next + delimiter.length();
    } 
    result.push_back(source.substr(last));
    return result;
}

now simply:

std::vector<std::vector<std::string>> parsedCSV;
while (getline(csvread, s, '\n'))
{
parsedCSV.push_back(split(s,";"));
}



回答2:


You should do the '\n' and ';' splitting separately:

while (getline(csvread, line, ';'))
{
    // in here, split line by ;
    std::vector<std::string> elems;
    boost::split(elems, line, boost::is_any_of(";"));

    // do something with elems
}



回答3:


I recently had to read csv-data as well and stumbled upon the same 'problem'. Here's what I did:

  1. Read in a full line with getline(csvread, s), this will read up to the first newline.
  2. Split the string on every occurence of ;, I've used this StackOverflow answer as inspiration to split a string, the code is also listed below.

I didn't care much for performance as I only had to run this program once, I won't comment on the speed of this workaround.

Good luck!

Edit: apparently Boost offers code to split a string, that might be cleaner, consider the code below if you want to avoid Boost.


#include <string>
#include <sstream>
#include <vector>

// source: https://stackoverflow.com/a/236803/4841248

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}



回答4:


try something like this:

std::vector<std::string> cells;
while (getline(csvread, s) ){
   boost::split(cells, s, boost::is_any_of(";"));
   ....
}


来源:https://stackoverflow.com/questions/30171443/c-read-csv-file-separated-by-and-n

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!