Search code examples
c++filetextdelimitergetline

Read in data from text file line by line, separated by multiple delimiters in C++


I have data in a text file which I wish to read in and split up to then create a new object out of.

I have found this code:

std::ifstream file("plop");
std::string   line;

while(std::getline(file, line))
{
    std::stringstream   linestream(line);
    std::string         data;
    int                 val1;
    int                 val2;

    std::getline(linestream, data, '\t');

    linestream >> val1 >> val2;
}

Which reads in a text document and splits it by line. However this code assumes the delimiter is always a tab. What if the data had more than one delimiter which would point to what type of data would follow it. i.e assuming a text file such as:

hey, "hi" (hello) [hola]
bye, "by" (byeee) [biii]

and I wanted to split the data into

String twoCharacters;
String threeCharacters;
String fourCharacters;
String fiveCharacters;

so

twoCharacters = hi and by

with the delimiter being two " and

threeCharacters = hey and bye

with the delimiter being a , after it

Any help would be greatly appreciated! Thanks.


Solution

  • You can just keep calling std::getline() with different delimiters:

    std::ifstream file("test.txt");
    
    std::string   line;
    while(std::getline(file, line))
    {
        std::stringstream linestream(line);
    
        std::string skip;
        std::string item1;
        std::string item2;
        std::string item3;
        std::string item4;
    
        std::getline(linestream, item1, ',');
        std::getline(linestream, skip, '"');
        std::getline(linestream, item2, '"');
        std::getline(linestream, skip, '(');
        std::getline(linestream, item3, ')');
        std::getline(linestream, skip, '[');
        std::getline(linestream, item4, ']');
    
        if(linestream) // true if there were no errors reading the stream
        {
            std::cout << item1 << '\n';
            std::cout << item2 << '\n';
            std::cout << item3 << '\n';
            std::cout << item4 << '\n';
        }
    }
    

    I used variable skip to read up to the beginning of the next field.