C++获取EOL的大小(以字节为单位)

8
我正在阅读一个ASCII文本文件。它由每个字段的大小(以字节为单位)定义。例如,每行包括10个字节的字符串、8个字节的浮点值、5个字节的整数等等。
我的问题是如何读取换行符,因为它的大小取决于操作系统(通常在Windows上为2字节,在Linux上为1字节)。
如何在C++中获取EOL字符的大小?
例如,在Python中,我可以这样做:
len(os.linesep)

4
如果您在文本模式下打开文件,则换行符应始终为'\n',无论本地行结束符是什么。您真的需要知道本地行结束符的大小吗? - Badministrator
文件是否保证在与读取它的代码运行的操作系统相同的操作系统下保存?如果是,则只需以文本(非二进制)模式打开文件。 - dxiv
2个回答

1
这个古老的方法是逐行读取。现在,最后一个字符应该是\n。去掉它。然后,查看前一个字符。它将是\r或其他内容。如果是\r,则去掉它。对于Windows [ascii]文本文件,没有其他可能性。即使文件是混合的(例如,有些行是\r\n,有些行只是\n),这也有效。您可以试着对几行进行操作,以确保您不会处理一些奇怪的东西。之后,您现在知道大多数文件的预期内容。但是,剥离方法是一种通用可靠的方法。在Windows上,您可以从Unix(或反之亦然)导入文件。

有一点挑剔,但是如果不事先知道行终止符是什么,很难“读取一行”。例如,您的方法无法处理\r行终止符,也无法处理在Windows环境中出现的连续空行保存为\r\n\n\n的情况。 - dxiv
1
@dxiv 这种方法适用于\r\n\n\n(例如\r\n \n \n)——这只是混合模式,就像我之前提到的那样[连续不是问题]。在20多年中,我从未见过仅包含\r的文件[即使有,我也已经转换了成千上万个文件]。现在许多程序都无法读取它们,因为它们至少假定有换行符。试试在DOS上使用type file命令;-) 我认为即使微软也不再支持它们了。'\r'在一行的_开头_是有效的[例如捕获进度输出]。我看到过更多这样的情况(例如\rpgm is 56% done\rpgm is 57% done)。 - Craig Estey
@user3690202 我早就猜到了,但这已经超出了OP问题的范围。这样的文件需要在导入时转换为[NTFS]文件系统才能在WinX下使用--因此OP永远不会看到它们的原始格式。它们可以自动检测/转换,但最好只是通过命令行选项“知道”。最快的逐行读取方式是通过mmap(请参见我的答案:https://dev59.com/MJDea4cB1Zd3GeqPiesP#33620968),因此首先进行预扫描非常容易,但在99.44%的情况下几乎不值得额外的努力。 - Craig Estey
@CraigEstey - 我可以想到很多方法来获取以CR结尾的文本文件。你可以使用Linux启动盘引导Windows机器并从旧驱动器复制文件等。重点是- OP没有提到Windows,将文件复制到Windows机器上并不会“导入FS”,如果你真的想要,甚至Vim也可以在Windows机器上生成CR行结束的文本文件。这似乎不是问题范围之外的事情-实际上它似乎是问题的整个重点,而你却错过了这一点。 - user3690202
@CraigEstey 我认为你需要学习如何使用Vim,并同时学习行尾是如何工作的。http://vim.wikia.com/wiki/File_format 将文件格式设置为mac,一切都正常了。你所说的“格式不正确”纯属胡说八道。算了吧,像你这样的人没有学习的能力。也许可以转向教科书-20年的经验,哈,那么你一定错过了MacOS 9,对吧? - user3690202
显示剩余2条评论

0

我不确定你认为翻译发生的位置是否正确。请看以下代码:

ostringstream buf;
buf<< std::endl;
string s = buf.str();
int i = strlen(s.c_str());

在Windows上运行后,i == 1。因此,在std中的行结束定义为1个字符。正如其他人所评论的那样,这是“\n”字符。


这段代码是错误的,因为CRT库不会将\n转换为\r\n以用于内存缓冲区,但对于文件和控制台则会这样做。 - Serge Rogatch
这里你正在展示我所面临的问题。C++在写入文件/控制台时会将“\n”转换为特定于操作系统的字符,但不会转换到缓冲区中。 - jramm
@jramm,我认为你还没有充分解释清楚你的问题。当写入缓冲区时,\n根本不需要进行编码(实际上也不能)。但是,当你将该缓冲区写入以文本模式打开的文件中时,\n将自动转换为平台所需的任何内容。然后,如果你以_text_模式打开同一文件并读取它,则换行序列将被转换回\n。因此,至少对我来说,不清楚为什么你需要知道磁盘上\n的编码方式。 - dxiv

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