5

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

user3353819
  • 911
  • 2
  • 8
  • 21
  • `std::getline` will transform `'\n'` into the system-specific newline. – chris Nov 20 '14 at 15:03
  • I'm dealing with a horrid example where (not my fault), data from an MS excel spreadsheet is copied into a Mac text file. It only works if I use `std::getline(data,str,'\r')`. In that instance it is not doing what you say. – user3353819 Nov 20 '14 at 15:05
  • Can you not check for both \n and \r\n? – kiss-o-matic Nov 20 '14 at 15:13
  • I'm asking how to do that. But it's not that simple. If it checks for `\r` it will find it even if the actual line break character being used is `\r\n` – user3353819 Nov 20 '14 at 15:14
  • according to getline definition: getline, "Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n')" So it sound like std::getline(data,str,'\r') is all you need – Pandrei Nov 20 '14 at 15:34
  • @Pandrei Not according to what I'm seeing. If I do that it will read in a 'line' full of linebreaks. – user3353819 Nov 20 '14 at 15:44
  • 2
    @Pandrei That isn't what the definition says: http://www.cplusplus.com/reference/string/string/getline/ It only searches for the newline character if the delim field isn't used – user3353819 Nov 20 '14 at 15:47

0 Answers0