C ++: reading CSV file, stripped; And n

Sorry if this is just sheer nonsense, but I'm stuck with the problem of reading files via C ++. This is the CSV data I would 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 would like to read the first values ​​(separated by ;;;;) and store them in a 2-dimensional array. It wouldn't be a problem if it was completely split by ";". But if you use

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

      

I am getting the following information: {5}{1}{0}{3}{3}{5}{5}{3}{3}{3}{3}{2}{3}{3}{0\n5}{1}

so it basically keeps the newline and doesn't consider it a delimiter.

So, is it possible to use getline even if you have two delimiters? Or am I completely disconnected? I also thought about reading line by line by adding a; to a string and rewrite it to a file to reuse getline using ;. But that might not be the best option, right?

+3


source to share


4 answers


you can use split 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 it's simple:

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

      

+2


source


You have to do the split '\n'

and ';'

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


source


I recently had to read csv data as well and came across the same "problem". Here's what I did:

  • Read the full line from getline(csvread, s)

    , this will be read to the first new line.
  • Split the string at each occurrence ;

    , I used this . See StackOverflow answer as inspiration for splitting a string, the code is also listed below.

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

Good luck!

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


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

// source: /questions/63/split-a-string-in-c/1384#1384

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;
}

      

+2


source


try something like this:

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

      

+2


source







All Articles