none
none

Reputation: 12137

c++ split string by double newline

I have been trying to split a string by double newlines ("\n\n").

input_string = "firstline\nsecondline\n\nthirdline\nfourthline";

size_t current;
size_t next = std::string::npos;
do {
  current = next + 1;
  next = input_string.find_first_of("\n\n", current);
  cout << "[" << input_string.substr(current, next - current) << "]" << endl;
} while (next != std::string::npos);

gives me the output

[firstline]
[secondline]
[]
[thirdline]
[fourthline]

which is obviously not what I wanted. I need to get something like

[first line
second line]
[third line
fourthline]

I have also tried boost::split but it gives me the same result. What am I missing?

Upvotes: 7

Views: 4884

Answers (3)

Roland
Roland

Reputation: 11

How about this approach:

  string input_string = "firstline\nsecondline\n\nthirdline\nfourthline";

  size_t current = 0;
  size_t next = std::string::npos;
  do
  {
    next = input_string.find("\n\n", current);
    cout << "[" << input_string.substr(current, next - current) << "]" << endl;
    current = next + 2;
  } while (next != std::string::npos);

It gives me:

[firstline
secondline]
[thirdline
fourthline]

as the result, which is basically what you wanted, right?

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361812

The reason why your code doesn't work is explained very well by @Benjamin in his answer. So I would show you an alternative solution.

No need to do manual splitting. For your specific case, std::stringstream is appropriate:

#include <iostream>
#include <sstream>

int main() {
        std::string input = "firstline\nsecondline\n\nthirdline\nfourthline";
        std::stringstream ss(input);
        std::string line;
        while(std::getline(ss, line))
        {
           if( line != "")
                 std::cout << line << std::endl;
        }
        return 0;
}

Output (demo):

firstline
secondline
thirdline
fourthline

Upvotes: -2

Benjamin Lindley
Benjamin Lindley

Reputation: 103761

find_first_of only looks for single characters. What you're telling it to do by passing it "\n\n", is to find the first of either '\n' or '\n', and that's redundant. Use string::find instead.

boost::split also works by examining only one character at a time.

Upvotes: 5

Related Questions