原始字符串文字中的回车符+换行符?

时间:2014-04-05 07:46:37

标签: c++ string gcc c++11 rawstring

考虑具有UNIX行结尾的C ++文件(即'\x0a'而不是"\x0d\x0a")并包含以下原始字符串文字:

const char foo[] = R"(hello^M
)";

(其中^M是实际字节0x0d(即回车))。

跟随字符串比较的结果应该是什么(在考虑原始字符串文字的标准定义时)?

strcmp("hello\r\n", foo);

字符串是否应该相等? (即0!=0?)

使用GCC 4.8(在Fedora 19上),他们比较不平等。

这是GCC中的错误或功能吗?

2 个答案:

答案 0 :(得分:4)

就标准而言,您只能在字符串文字(以及程序中的其他位置)中使用基本源字符集的成员。如何将程序的物理表示映射到基本源字符集是实现定义的。

g ++显然认为ASCII \ x0a,ASCII \ x0d和ASCII \ x0d \ x0a都是名为“newline”的基本源字符集成员的有效表示。这是完全合理的,因为在Windows,Unix和Mac OS X Classic机器之间传输的源代码需要保持其含义。

答案 1 :(得分:0)

原始字符串文字不是完全原始的,因为它们是通过读取并解释输入C ++文件的编译器到达您的程序的。在填充2个字符串之前,您可以检查原始字符串的大小-它与预期的^ M(\ x0d)个字符的数量不同。

您可以求助于以二进制形式读取数据,例如(binary read/w example):

std::ifstream infile ("test.txt", std::ifstream::binary);
infile.seekg (0,infile.end);
long size = infile.tellg();
infile.seekg (0);
char* buffer = new char[size];
infile.read (buffer,size);

或者您可以坚持使用原始文字,但是要有一些技巧-用文字中的其他字符替换所有“坏”字符,然后在使用此文字时进行反向替换,例如:

... all includes ...

std::string str = R"(hello|
)";

int main()
{
  std::replace(str.begin(), str.end(), '|', '\015');
  std::cout << strcmp("hello\r\n", str.data()) << std::endl;
}