특히 나는에 관심이 istream& getline ( istream& is, string& str );
있습니다. 모든 개행 인코딩을 내부적으로 '\ n'으로 변환하도록 지시하는 ifstream 생성자에 대한 옵션이 있습니까? getline
모든 라인 엔딩을 우아하게 처리하고 호출 할 수 있기를 원합니다 .
업데이트 : 명확히하기 위해 거의 모든 곳에서 컴파일되고 거의 모든 곳에서 입력을받는 코드를 작성할 수 있기를 원합니다. '\ n'없이 '\ r'이있는 희귀 파일을 포함합니다. 소프트웨어 사용자의 불편을 최소화합니다.
문제를 해결하는 것은 쉽지만 표준에서 모든 텍스트 파일 형식을 유연하게 처리하는 올바른 방법이 궁금합니다.
getline
문자열로 최대 '\ n'까지 전체 줄을 읽습니다. '\ n'은 스트림에서 소비되지만 getline은 문자열에 포함하지 않습니다. 지금까지는 괜찮지 만 문자열에 포함되는 '\ n'바로 앞에 '\ r'이있을 수 있습니다.
텍스트 파일 에는 세 가지 유형의 줄 끝이 있습니다. '\ n'은 유닉스 머신의 일반적인 끝, '\ r'은 (내 생각에) 오래된 Mac 운영 체제에서 사용되었으며 Windows는 '\ r'쌍을 사용합니다. 뒤에 '\ n'.
문제는 getline
문자열 끝에 '\ r' 을 남긴다 는 것입니다 .
ifstream f("a_text_file_of_unknown_origin");
string line;
getline(f, line);
if(!f.fail()) { // a non-empty line was read
// BUT, there might be an '\r' at the end now.
}
편집 것을 지적 닐 덕분에 f.good()
내가 원하는 것이 아니다. !f.fail()
내가 원하는 것입니다.
직접 수동으로 제거 할 수 있으며 (이 질문 편집 참조) Windows 텍스트 파일의 경우 쉽습니다. 하지만 누군가 '\ r'만 포함 된 파일을 제공 할까 봐 걱정됩니다. 이 경우 getline이 전체 파일을 소비하고 단일 라인이라고 생각합니다!
.. 그리고 그것은 유니 코드를 고려하지도 않습니다 :-)
.. 아마도 Boost는 텍스트 파일 유형에서 한 번에 한 줄을 소비하는 좋은 방법이 있습니까?
편집 Windows 파일을 처리하기 위해 이것을 사용하고 있지만 여전히 그럴 필요가 없다고 느낍니다! 그리고 이것은 '\ r'전용 파일에 대해 포크되지 않습니다.
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}