std::getline deal with \n, \r and \r\n

14.3k views Asked by At

I'm reading data in from a text file and do so line by line using std::getline. This by default reads up to a newline character \n. My code relies on this.

However, it turns out I have to deal with data that may be generated in different environments ie where the newline character is \r (Mac), \n (Unix) or \r\n (Windows)

Is there a simple fix so that I can do something like

std::getline(data,str,'\r\n','\r','\n');

but get it to first look for \r\n and then \r and \n so that it will return a 'line' independently of whatever environment generated it?

Or more generally: Is there a way of using std::getline to return a 'line' for any type of commonly used line break/carriage return?

At the moment all I have come up with is

std::vector<int> size(3);
for (int i=0;i<3;i++){

    data.open(c_string_file_name);
    switch (i){
        case 0: std::getline(data,str,'\r\n');size[0]=str.size();break;
        case 1: std::getline(data,str,'\r');size[1]=str.size();break;
        case 2: std::getline(data,str,'\n');size[2]=str.size();break;
    }
    data.close();

}

int min=std::min_element(size.begin(),size.end());

std::string delim;

switch (min){
    case 0:delim='\r\n';break;
    case 1:delim='\r';break;
    case 2:delim='\n';break;
}
if ((size[0]==size[1])&&(min==1)){
    delim='\r\n';
}
//rest of code use

std::getline(data,str,delim.c_str());

Based on the assumption that, assuming there are line breaks, the relevant delimiter will produce the shortest 'line'. Also accounting for the fact that \r and \r\n will have the same length string if it is an \r\n delimiter

0

There are 0 answers