std :: getline()读取马车返回 r,如何避免
std::getline() reads carriage return into the string, how to avoid that?
我需要从一个 Stern
(engl。:star)对象的t t t t t thex文件中读取所有属性。我需要用""
替换字符串"leer"
,但也可以有一个有效的字符串,不应用""
替换。
即,对于另一个Stern
对象,也可能有"leer"
而不是"Sol"
。
问题:
问题是它不会用""
替换"leer"
。似乎它将"leer\r"
保存在对象中,而不仅仅是"leer"
中,但我也尝试替换"leer\r"
,但它仍然不起作用。
这是文本文件中应读的一个Stern
:
0
Sol
0.000005
0.000000
0.000000
leer
1
0
这是我的operator >>
阅读它:
istream& operator>>(istream& is, Stern& obj)
{
string dummy;
is >> obj.m_ID;
getline(is, dummy);
getline(is, obj.m_Bez);
if (obj.m_Bez == "leer")
obj.m_Bez = "";
is >> obj.m_xKoord >> obj.m_yKoord >> obj.m_zKoord;
getline(is,dummy);
getline(is,obj.m_Sternbild);
if (obj.m_Sternbild == "leer")
obj.m_Sternbild = "";
is >> obj.m_Index >> obj.m_PrimID;
return is;
}
stern.h:
#ifndef STERN_H
#define STERN_H
#include <string>
#include <iostream>
using namespace std;
class Stern
{
public:
Stern();
// 2.a)
//Stern(int m_ID, string m_Bez, float m_xKoord, float m_yKoord, float m_zKoord, string m_Sternbild, int m_Index, int m_PrimID);
virtual ~Stern();
void print() const; // 1.b)
friend ostream& operator<<(ostream& os, const Stern& obj); // 1.b)i.
friend istream& operator>>(istream& is, Stern& obj);
private:
int m_ID;
string m_Bez;
float m_xKoord;
float m_yKoord;
float m_zKoord;
string m_Sternbild;
int m_Index;
int m_PrimID;
};
#endif /* STERN_H */
问题在于,在Windows中,Newline在CR + LF
中表示为:"rn"
,在UNIX中,它是LF
,它只是"n"
。
您的std::getline(...)
命令正在读取直到"leerrn"
中的"n"
并丢弃"n"
,您所产生的字符串将是:
"leerr"
要解决此问题并在UNIX/Windows之间转换文件,有2个工具dos2unix
和unix2dos
。Ubuntu等效物为fromdos
和todos
,您将需要fromdos
将Windows文本文件转换为Unix文本文件。
要测试文件使用CR + LF
或LF
您可以做:
dos2unix < myfile.txt | cmp -s - myfile.txt
在Unix&amp;Linux Stackexchange网站。
似乎它将
"leer\r"
保存在对象中,而不仅仅是"leer"
中,但我也尝试替换"leer\r"
,但仍然无法使用。我仍然不明白为什么我的if (obj.m_Sternbild == "leer\r")
不起作用,因为IMO应该有效吗?
应该是:
if (obj.m_Sternbild == "leerr")
没有逃脱后斜线,因为
r
已读取到字符串中。
编辑:
AS @freelanceconsultant 在下面的评论中写:上述答案不是一般解决方案。因为在Windows或Unix上编译的二进制文件应适用于两个平台的文本文件。
有两种解决方案。
显而易见的是,与输入的两个不同版本进行比较。使用std::getline
Windows结果是"leerr"
,UNIX结果是"leer"
。
if (obj.m_Sternbild == "leerr" || obj.m_Sternbild == "leer")
另一个解决方案是将newline表示形式归一化为一种形式,而仅对此形式进行检查。这是一个口味和性能的问题,因为您需要创建新的字符串。以他的答案为例。
您可以使用它来删除std::getline
返回的任何不需要字符。
// std::string s;
// std::getline(input, s);
s.erase(std::remove(s.begin(), s.end(), 'r' ), s.end());
s.erase(std::remove(s.begin(), s.end(), 'n' ), s.end());
这在Linux系统上起作用,其中输入文件格式使用了Line Endings CRLF
。这是因为在Linux系统上,std::getline
正在搜索n
字符,因此它在每行末端返回一个额外的r
。
我不会期望这能像您在其他系统上的预期一样工作。例如,它可能是:
- 在OS X上,
getline
可能搜索r
,含义后续调用返回一个带有n
的 string 。(以上将可能仍然有效,因为您仍然删除n
。 - 在Windows上,
getline
搜索rn
。如果在OS X或Linux上产生文件,我将假设getline
无法将输入分为不同的行,而只返回整个输入。 - 我不确定上述两个点,并且都没有测试任何一种情况,因为我碰巧没有可用的OS X系统或用于开发工作的Windows系统设置。
,似乎它保存在对象中,而不是仅保存在对象中 " leer"
您可以修剪从getline
获得的字符串,也可以与stringstream
结合使用getline
:
std::string line;
getline(is,line);
std::stringstream ss(line);
std::string trimmed_string;
ss >> trimmed_string;
现在trimmed_string
将仅包含所需的字符串,无端线,训练或领先的空格或其他东西。
ps:这仅在要读取的字符串不包含空格本身时才有效。如果这样,您必须诉诸于从 getline
获得的字符串进行按摩或选择一些特殊角色,或者在阅读后选择一些特殊字符(例如,阅读" alpha_centauri",然后用" _"替换为"获取" alpha centauri")。
- 如何避免模板函数返回类型重复?
- 避免在返回当前对象时复制
- lower_bound 在 C++ STL 中返回迭代器,即使元素不存在也是如此.如何避免这种情况?
- 如何避免使用多个if-else来检查返回值是否为错误代码?
- 避免多个返回语句的方法
- 在C++11中按值返回构造的对象时,避免复制构造函数调用
- 如何避免布尔和返回它的方法之间的名称碰撞
- 如何避免将const-ref返回缓存中的临时性
- 是否可以避免使用lambda中的尾随返回型语法
- std :: getline()读取马车返回 r,如何避免
- 避免从函数返回时进行复制,而不依赖编译器优化
- 如何避免验证触发后返回时被解雇
- 如何避免在类中返回指针
- 避免通过引用返回参数
- 如何避免内存泄漏与返回常量字符*
- 在从函数返回值时使用std::move()以避免复制
- 返回指向类成员的指针 - 我应该避免它
- 如何避免在分配/返回时破坏对象
- C++11 在特定情况下避免冗余返回类型
- 我可以避免返回函数的模板返回类型吗?