是否有可能知道从文件中读取的长文本将在 C 中使用多少个字符?

Posted

技术标签:

【中文标题】是否有可能知道从文件中读取的长文本将在 C 中使用多少个字符?【英文标题】:Is it possible to know how many characters long text read from a file will be in C? 【发布时间】:2021-03-04 00:15:22 【问题描述】:

我知道在 C++ 中,你可以检查字符串的长度,但在 C 中,就不行了。

是否可以知道文本文件的文件大小,知道文件中有多少个字符?

是每个字符一个字节,还是其他标题被秘密存储,无论我是否设置它们?

出于性能原因,我想避免在遍历文件时对每个字符执行空值检查。

谢谢。

【问题讨论】:

这能回答你的问题吗? How do you determine the size of a file in C? 看你怎么定义性格?如果是任何 UTF 编码,不,无法知道字符数。如果它是 ASCII 或其他每字符一个字节的编码,文件的大小将主要告诉您(除非您需要将 CRLF 折叠为 LF 以进行计数)。也就是说,标准 C 没有解决方案,您只能使用系统 API 来获得想法。不过,您不会进行NULL 检查; C API 要么给你行(在这种情况下,好吧,NUL 检查告诉你字符串在哪里结束),而字符驱动的 API 返回 EOF,基于块的 API 返回读取的字节数。跨度> 即使您确定了大小,也不能安全地跳过检查,因为文件内容可能被系统上的其他程序更改,或者可能存在 I/O 错误。 另请注意,在使用 CRLF 行尾的 Windows 等系统上,您可以从文本文件中读取的字符数不等于其大小(以字节为单位)。 @NateEldredge 链接的问题有点陷阱,因为仔细阅读答案表明除了打开文件并读取每个字符之外,没有可移植的方法(无论是文本文件还是二进制文件)跨度> 【参考方案1】:

您可以打开文件并读取所有字符并计算它们。

除此之外,没有完全可移植的方法来检查文件的长度——既不是在磁盘上,也不是根据要读取的字符数。这适用于文本文件和二进制文件。

How do you determine the size of a file in C? 克服了一些陷阱。也许其中一个解决方案适合您运行代码的系统子集;或者您可能想使用 POSIX 或操作系统调用。


如 cmets 中所述;如果问题背后的意图是读取字符并即时处理它们,那么即使您知道文件大小,您仍然需要检查读取错误,因为读取可能会失败。

【讨论】:

“因为阅读可能会失败” - 并且文件可能会在您阅读它们时发生变化 :-) @paxdiablo 仅在使用允许读取可写入的文件的劣质操作系统时;) @M.M 那些玩具操作系统只有那些需要额外保护的人才需要...... ;-) @M.M:我知道你在开玩笑,但很好奇:有没有常见的操作系统可以做到这一点?我知道 Windows 的 CreateFile 有一个 FILE_SHARE 权限的概念(并且根据它实现的标准 C API 在共享方面可能很吝啬),但是只要两个句柄都可以读取独立打开以进行写入的文件以适当的共享标志打开。是否有常见的操作系统无法打开已打开文件的读取句柄以进行写入,反之亦然?我想不出任何想法,但我很幸运大部分时间只需要考虑 Windows 和 Linux。【参考方案2】:

字符(char 类型)是单字节值,如 C 标准 (see CHAR_BIT) 中所定义。 NUL character 也是一个字符,因此它也占用一个字节。

因此,如果您使用的是 ASCII 文本文件,文件大小将是字节数,因此相当于字符数。

如果您询问单个 字符串 在文件中的长度,那么您确实需要查找 NUL 和其他扩展字符字节并在此基础上计算字符串长度。您可能无法安全地假设只有一个 NUL 字符并且它位于文件的末尾,具体取决于该文件的制作方式。您还可以排除换行符和其他扩展字符。您必须决定一个字符集并从该字符集开始计数。

此外,如果您正在处理包含以 Unicode 等编码的多字节字符的文件,那么这将是一个不同的答案。您可以使用different functions 来读取使用多字节编码的文本文件。

所以答案将取决于您的文本文件使用的编码类型,以及您是在计算字符还是字符串长度,这是两种不同的衡量标准。

【讨论】:

第二段不正确:从文本文件中读取的字符可能是磁盘上多个字节的翻译,常见的例子是 Windows 行尾 Windows 行尾由两个字符(\r\n)组成,因此占用两个字节。同样,您必须仔细定义字符的含义。 也许你可以澄清第二段,目前似乎是说程序接收到的字节数将等于文件中的字节数(这是不正确的)跨度> @M.M 除了 windows 之外,还有其他执行 CRLF -> LF 翻译的平台吗?除了 0x1a 之外,你能再举一个例子吗(同样,windows niceties)。

以上是关于是否有可能知道从文件中读取的长文本将在 C 中使用多少个字符?的主要内容,如果未能解决你的问题,请参考以下文章

保存名称从文本框中读取的文件。 C#

SQL 读取 Where IN(来自 .TXT 文件的长列表)

使用没有无限循环的 C++ i 检测文本文件中的更改?

用C读取文本文件的好方法

从 c# windows 窗体中的图像中读取文本

如何将在c语言中生成的数据保存到文本文件中?