ฉันสนใจistream& getline ( istream& is, string& str );
โดยเฉพาะ มีตัวเลือกสำหรับตัวสร้าง ifstream เพื่อบอกให้แปลงการเข้ารหัสบรรทัดใหม่ทั้งหมดเป็น '\ n' ภายใต้ประทุนหรือไม่ ฉันต้องการที่จะสามารถโทรgetline
และให้มันจัดการกับจุดสิ้นสุดของบรรทัดทั้งหมดได้อย่างสง่างาม
อัปเดต : เพื่อความชัดเจนฉันต้องการที่จะสามารถเขียนโค้ดที่รวบรวมได้เกือบทุกที่และจะรับข้อมูลจากเกือบทุกที่ รวมถึงไฟล์หายากที่มี "\ r" โดยไม่มี "\ n" ลดความไม่สะดวกสำหรับผู้ใช้ซอฟต์แวร์ใด ๆ
เป็นเรื่องง่ายที่จะแก้ไขปัญหานี้ แต่ฉันยังคงสงสัยเกี่ยวกับวิธีที่ถูกต้องในมาตรฐานเพื่อจัดการกับรูปแบบไฟล์ข้อความทั้งหมดได้อย่างยืดหยุ่น
getline
อ่านเป็นบรรทัดเต็มถึง '\ n' เป็นสตริง '\ n' ถูกใช้จากสตรีม แต่ getline ไม่รวมไว้ในสตริง จนถึงตอนนี้ แต่อาจมี "\ r" อยู่ก่อนหน้า "\ n" ที่รวมอยู่ในสตริง
มีสามประเภทของการสิ้นสุดบรรทัดที่เห็นในไฟล์ข้อความ: '\ n' คือการลงท้ายแบบเดิมบนเครื่อง Unix '\ 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 จะกินทั้งไฟล์โดยคิดว่ามันเป็นบรรทัดเดียว!
.. และนั่นยังไม่ได้พิจารณา Unicode ด้วยซ้ำ :-)
.. บางที Boost อาจมีวิธีที่ดีในการใช้ทีละบรรทัดจากไฟล์ข้อความประเภทใดก็ได้?
แก้ไขฉันใช้สิ่งนี้เพื่อจัดการไฟล์ Windows แต่ฉันยังรู้สึกว่าไม่ควรทำ! และสิ่งนี้จะไม่แยกสำหรับไฟล์ "\ r'-only
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}