【问题标题】:How can tell the end of a line with c如何用c判断一行的结尾
【发布时间】:2013-03-18 22:25:15
【问题描述】:

我不知道该行是否以 '\n' 或 '\r' 或 '\r\n' 结尾 并且不要对文本进行什么编码,除非编码是utf-8,否则它可以是no bom。 是否有函数或库可以做到这一点,或者只是告诉我一行的终止。

【问题讨论】:

  • 如果您不知道编码,则无法确定。考虑字节序列30 0A。除非您知道编码,否则无法判断这是数字“0”后跟换行符的 ASCII 表示,还是字符“《”的 UTF16-BE 表示。所以,首先你需要一个库来猜测字符编码,然后你可以考虑换行。
  • 您的意思是任何文本编码,还是总是 ASCII/UTF-8 但使用不同的行终止符?
  • @teppic 不,不是,也可以是GBK。
  • @SteveJessop 如果假设如果是GBK编码那么终结符是'\r\n',如果是utf8,编码终结符是'\n',那么有没有更好的办法呢?

标签: c text encode


【解决方案1】:

您是否偶然在打开以读取文本的文件上使用了fgetsfreadfputsfwrite 等?如果是这样,该实现将在读取时自动将特定于操作系统的行终止符(例如"\r\n")转换为'\n',并在写入时将'\n' 转换为特定于操作系统的行终止符。


还有两个其他场景,其中一个原来是 OP:

  1. OP 一直在努力解决 "\r\n" 从其他操作系统软件继承而来的问题,因此在他的(可能是类 Unix 的)操作系统中打开文件进行读取将不再转换它。我的建议是使用dos2unix 进行这些一次性转换,而不是用可能永远不会再次运行的东西来膨胀你的代码。
  2. 您没有使用这些功能之一。这可能是因为您正在使用诸如套接字之类的流,并且协议可能需要"\r\n"。在这种情况下,您应该使用strstr 找到确切的序列"\r\n"

UTF-8 的设计考虑到了与 ASCII 的一定程度的兼容性,因此您可以假设任何使用 UTF-8 的系统也将使用 ASCII 或一些类似的字符集。任何使用大于一个字节的序列的字符将只使用 0x80 或更大的值来表示。由于'\n' 位于 0x00-0x7F 范围内,因此可以保证它是单字节,并且不会作为多字节字符的一部分存在。

【讨论】:

  • 不幸的是,在文本模式下阅读它不会在阅读时将非操作系统特定的\r\n 变成\n。因此,如果您需要应对有人将文本文件从 Windows 复制到 Linux 的可能性,您需要另一种解决方案。
  • @SteveJessop 虽然我同意有人混淆编码很烦人,但存在一些实用程序可以为您执行这种转换。为什么要重新发明轮子?如果您花 15 分钟计算每个特定于操作系统的行结尾,那么您最终会得到一个非常复杂的解决方案来解决一个简单的问题。
  • @choury 您的程序处理不同的操作系统是否很常见,或者这是您很少看到您的程序处理的问题(例如,您的程序是否主要处理相同的文本文件?操作系统)?当您可以在程序之外使用其他程序(例如dos2unixunix2dos)为您执行转换时,为什么还要引入膨胀?
  • @modifiablelvalue 是的,大部分文件来自同一个操作系统,但其余部分也必须处理。我不知道文件来自哪个操作系统。
  • @choury 啊,所以您打算将 LF 解释为 Unix 的行终止符,CR+LF 解释为 MS-DOS/Windows(Windows 7 之前)的行终止符,LF+CR作为 RISC OS 的行终止符,CR 作为 MacOS(前 MacOSX)的行终止符,RS 用于 QNX,NL 用于 z/OS 以及更多作为换行符?太臃肿了...您是否也将'N' 解释为换行符?
【解决方案2】:

使用 wcslen 获取 utf8 字符串的字节大小。

http://linux.die.net/man/3/wcslen

【讨论】:

  • 这与线路终止有什么关系?
  • 除非他在他的源代码中使用某种内存映射,否则他可能会在 char 数组中包含该行。他还说可以是utf8。拥有 utf8 字符串的字节大小也可以得到字符串的实际大小,开始 + 大小 = 行尾。
  • 但来源只是纯文本(不仅仅是英文)。因为是在*nix或者windows下创建的(不是我自己创建的),所以格式不具体。
  • 然后也许看看 Enca “Enca 是一个非常朴素的字符集分析器。它检测文本文件的字符集和编码,还可以使用内置转换器或外部转换器将它们转换为其他编码libiconv、librecode 或 cstocs 等库和工具。” cihar.com/software/enca 然后根据编码调整程序的工作方式
  • 好的,我去看看它的源文件,看看能不能找到什么东西
猜你喜欢
  • 2021-11-25
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 2011-09-21
相关资源
最近更新 更多