在C++中从字符串中移除\r

19

在一个C++程序中,有时需要读取一个字符串,例如:

"NONAME_1_1\r"

\r给我带来了麻烦。我猜它会打印或添加类似于“^M”的东西,对吗?不管怎样,它给我造成了问题,我想摆脱它。

我不能修改输入。我想知道在这种情况下,如何使用C ++以最简单的方式删除该字符串中的\r

我知道如何在bash上执行此操作,但在C ++方面一无所知。

谢谢。


1
你是如何读取字符串的?你使用iostreams吗?请发布相关代码。 - Björn Pollex
这听起来像是在C语言中使用strtok的典型用法。 - svens
只有一个最后的问题,当逐个比较字符串字符时,我认为“\r”会占用两个字符,但实际上不是,它只占用一个字符。如果我想使用条件语句,应该怎么写?例如:if char[4]==`\r' ??? - Open the way
4个回答

47

我假设你说的“string”是指 std::string

如果只需要删除字符串的最后一个字符,你可以这样做:

mystring.pop_back();

mystring.erase(mystring.size() - 1);

编辑: pop_back()是C++的下一个版本,抱歉。

在进行一些检查后:

if (!mystring.empty() && mystring[mystring.size() - 1] == '\r')
    mystring.erase(mystring.size() - 1);

如果你想要移除所有的 \r,你可以使用:

mystring.erase( std::remove(mystring.begin(), mystring.end(), '\r'), mystring.end() );

只有一个最后的问题,当逐个比较字符串字符时,我认为“\r”会占用两个字符,但实际上不是,它只占用一个字符。如果我想使用条件语句,应该怎么写?例如:if char[4]==`\r' ??? - Open the way
@Werner:反斜杠引入转义序列。\r是回车符,ASCII码十进制13/十六进制0D,^M等。在单引号中,它是一个单字符常量;在双引号中,它将成为由两个字符组成的字符串字面值:ASCII 13和终止空值。 - CB Bailey
谢谢您的帖子。我知道必须有一种简单的方法来清理旧的Mac和Windows文件编码中的文件行。所以现在我首先运行getline(File,line),没有第三个参数来删除\n,然后我使用您的示例来清除任何\r。它似乎正在工作。谢谢。如果没有这个,每个循环的我的令牌向量的最后一个索引中会留下垃圾。我相信这是编码\r的问题。 - Miek

0

如果您想保留原始字符串并且想要删除多个字符(例如此示例中的CR和LF),则copy_if非常有用。

const std::string input = "Hello\r\nWorld\r\n";
std::string output;
output.reserve(input.length());

std::copy_if(input.begin(), input.end(),
           std::back_inserter(output),
           [] (char c) { return c != '\r' && c != '\n'; });

0

这取决于你如何在内存中保存它:

  1. 如果它在std::string中,只需检查最后一个字节,如果是'\r',则删除它。
  2. 如果它在const char*中,您可以使用strncpy将字符串复制到另一个char数组中,并有条件地获取最后一个字节。
  3. 如果“我无法修改输入”仅意味着您无法触摸源文件,则可以选择将其读入char数组中,并将任何尾随的'\r'替换为'\0'

我明白了。那么,就像检测 \r 一样简单吗?你能告诉我你会如何做吗?非常感谢。 - Open the way
@Werner,我不知道你是如何表示输入的。在你的问题中提供一些示例代码会很有帮助。 - Marcelo Cantos

0

在将文件在Unix和Windows之间移动后,从文件中读取行时会出现常见问题。

  • Unix变体使用"\n"(换行符)终止行。
  • Windows使用"\r\n"(回车符,换行符)终止行。

您可以运行“dos2unix”或“unix2dos”来转换文件中的行。


1
然后使用Charles Bailey的解决方案。 - Stephen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接