我一直在阅读ISO 14882:2003。它说:
S-CHAR:
源字符集的任何成员,除了双引号“,反斜杠\”或换行符之外 逸出序列
通用字符名称
现在,关于换行符,当行结尾为'\ r'时,我发现问题 我写了一个小cpp程序:
#include <fstream>
#include <string>
int main()
{
const char* program=""
"#include <string>\n"
"int main()\n"
"{\n"
" std::string s;\n"
" //s=\"\r"
" //\r"
" //\r"
" //\r"
" //\";\n"
" s=\"\\xAE\\xfffactory\\xAE\\xffaction\";\n"
" return 0;\n"
"}\n"
;
std::ofstream file("file.cpp", std::ios_base::trunc);
file << program;
file.close();
return 0;
}
在Windows上,file.cpp(在VS编辑器中读取)是:
#include <string>
int main()
{
std::string s;
//s="
//
//
//
//";
s="\xAE\xfffactory\xAE\xffaction";
return 0;
}
编译file.cpp时,VS触发并在第6行中出错,而不是第10行。
在Linux上,file.cpp(如emacs中所读)是:
#include <string>
int main()
{
std::string s;
//s="^M //^M //^M //^M //";
s="\xAE\xfffactory\xAE\xffaction";
return 0;
}
用gcc编译file.cpp我在第10行得到一个错误,而不是在第6行。
我应该从中得出什么结论?
答案 0 :(得分:6)
你应该得出结论:
\r
行结尾,因此它实际上将";
行计为第6行。emacs
无法理解\r
行结尾(至少默认情况下),因此它会在一行中显示来源。啊,你从标准中提供的报价也是无关的。 换行指的是源字符集,而不是字符串中的\r
和\n
。您引用的语法规则只排除字符串文字,例如:
const char* s = "some text, here comes 'new-line'
ha ha ";
答案 1 :(得分:1)
第2.1节[lex.phases]。第一阶段的翻译是:
物理源文件字符以实现定义的方式映射到基本源字符集(如果需要,引入行尾指示符的换行符)。 ...
换句话说,实现可以自由使用它想要的任何行结束约定,并在翻译的第一阶段将其转换为换行符。
实际上,在任何现代编译器中使用换行符都可以安全地使用换行符。
答案 2 :(得分:0)
Windows和Linux使用不同的行结束约定。在linux上,行尾为0x0A
,在Windows上为0x0D, 0x0A
。 C / C ++程序本身就是文本文件,并且通常可以跨平台进行互操作,只要您符合平台上的文本约定即可。
dos2unix(1)
工具仅用于此任务。
或者,由于您在自己的工具中动态生成此代码,因此您可以提供一个选项,告诉它使用一个行结束样式或另一个。
答案 3 :(得分:0)
现在,关于换行符,当行结尾为'\ r'时,我发现问题...
'\ r'是回车而不是换行符 - 所以我不确定问题是什么?
Windows选择将\ r \ n表示为换行符,但这并不意味着它们实际上是换行符