MSVC 和 g++ 中的不同行尾
Posted
技术标签:
【中文标题】MSVC 和 g++ 中的不同行尾【英文标题】:Different line endings in MSVC and g++ 【发布时间】:2020-12-04 10:35:11 【问题描述】:我正在尝试解析文件中的文本,我必须在其中检测空行。 我在 2 个地方运行代码:
win 10,视觉工作室 2019(MSVC) 在 WSL、ubuntu 20.04、g++ 下相同的计算机,相同的文件,相同的代码。
while (getline(inputFile, line))
if (line.length() == 1)
std::cout << "Empty line" << std::endl;
/*blabla*/
使用此代码,MSVC 不会打印空行,而 g++ 会。
if (line.empty())
std::cout << "Empty line" << std::endl;
使用此代码,MSVC 会找到空行,而 g++ 不会。
if (int(line[0]) == 10 || int(line[0]) == 13)
std::cout << "Empty line" << std::endl;
使用此代码 g++ 会找到空行,MSVC 不会
-
改变行尾的是Linux内核还是编译器?
在每个系统上始终检测行尾和空行的正确方法是什么?
【问题讨论】:
\r
, \n
可以替换幻数 10,13。
行尾的约定取决于操作系统。有 Windows 约定 (\r\n
) 和 Unix 约定 (\n
),老前辈记得经典的(在 OS X 之前)Mac 约定 (\r
)。如果您在不同的操作系统之间传输文本文件,您需要使用某种工具重新编码它们,或者准备好解析程序中的不同行尾。自然地,Unix 程序会将\r
视为常规字符而不是行尾序列的一部分。丢弃它是你的责任。
注意:在空行上执行line[0]
会使程序具有未定义的行为。
您可能需要检查常见的unix2dos
和dos2unix
工具,它们在\n
之前添加或删除\r
。
【参考方案1】:
您的困难源于您在同一台机器上混合了 Windows 和 Linux 行尾。 WSL 是一个类似 Linux 的环境,在 WSL 上处理 Windows 文件与在真正的 Linux 机器上处理它们没有什么不同,即有问题。
std::getline
去除\n
(0x0A) 行尾,另外在MSVC 中,以文本模式读取文件会自动去除\r
(0x0D) 字符。后者不会在 Linux 上发生。
因此,在非 Windows 平台上读取 Windows 文本文件(以 \r\n
行结尾)将删除 \n
,但将 \r
留在行尾。
如果您想处理这种情况,您可以手动去除尾随的\r
。例如
while (std::getline(inputFile, line))
if (!line.empty() && line.back() == '\r')
line.pop_back();
if (line.empty())
std::cout << "Empty line" << std::endl;
在调试时以二进制模式打印出line
通常很有帮助,因为\r
和\n
是不可见字符。
【讨论】:
以上是关于MSVC 和 g++ 中的不同行尾的主要内容,如果未能解决你的问题,请参考以下文章