std::getline имеет дело с \n, \r и \r\n

Я читаю данные из текстового файла и делаю это построчно, используя std::getline. По умолчанию это читается до символа новой строки \n. Мой код основан на этом.

Однако оказывается, что мне приходится иметь дело с данными, которые могут быть сгенерированы в разных средах, например, где символ новой строки равен \r (Mac), \n (Unix) или \r\n (Windows).

Есть ли простое решение, чтобы я мог сделать что-то вроде

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

но заставить его сначала искать \r\n, а затем \r и \n, чтобы он возвращал «строку» независимо от того, какая среда ее сгенерировала?

Или в более общем плане: есть ли способ использовать std::getline для возврата "строки" для любого типа часто используемого разрыва строки/возврата каретки?

На данный момент все, что я придумал, это

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());

Исходя из предположения, что при наличии разрывов строк соответствующий разделитель создаст самую короткую «строку». Также учитывается тот факт, что \r и \r\n будут иметь строку одинаковой длины, если это разделитель \r\n.


person user3353819    schedule 20.11.2014    source источник
comment
std::getline преобразует '\n' в новую строку для конкретной системы.   -  person chris    schedule 20.11.2014
comment
Я имею дело с ужасным примером, когда (не по моей вине) данные из электронной таблицы MS Excel копируются в текстовый файл Mac. Это работает, только если я использую std::getline(data,str,'\r'). В этом случае он не делает то, что вы говорите.   -  person user3353819    schedule 20.11.2014
comment
Вы не можете проверить и \n, и \r\n?   -  person kiss-o-matic    schedule 20.11.2014
comment
Я спрашиваю, как это сделать. Но это не так просто. Если он проверит \r, он найдет его, даже если фактически используемый символ разрыва строки \r\n   -  person user3353819    schedule 20.11.2014
comment
в соответствии с определением getline: getline, извлекает символы из is и сохраняет их в str до тех пор, пока не будет найден символ разделителя (или символ новой строки, '\n'). Так что это звучит как std::getline(data,str,'\r ') это все, что тебе нужно   -  person Pandrei    schedule 20.11.2014
comment
@Pandrei Не судя по тому, что я вижу. Если я это сделаю, он будет читаться в «строке», полной разрывов строк.   -  person user3353819    schedule 20.11.2014
comment
@Pandrei Это не то, что говорит определение: cplusplus.com/reference/string/ string/getline Он ищет символ новой строки только в том случае, если поле разделителя не используется   -  person user3353819    schedule 20.11.2014