7

在一个项目中,我必须读取一个文件,并且我必须处理文件中的字符数,有没有办法在不逐字符读取的情况下获取字符数(否则我将不得不读取文件两次,一次只是为了找到其中的字符数)。

甚至可能吗?

4

5 回答 5

11

是的。

寻尾得到端的位置即大小。

FILE*  file = fopen("Plop");
fseek(file, 0, SEEK_END);
size_t  size = ftell(file);      // This is the size of the file.
                                 // But note it is in bytes.
                                 // Also note if you are reading it into memory this is
                                 // is the value you want unless you plan to dynamically
                                 // convert the character encoding as you read.

fseek(file, 0, SEEK_SET);        // Move the position back to the start.

在 C++ 中,流具有相同的功能:

std::ifstream   file("Plop");
file.seekg(0, std::ios_base::end);
size_t size = file.tellg();

file.seekg(0, std::ios_base::beg);
于 2012-02-03T16:48:33.510 回答
8

你可以试试这个:

FILE *fp = ... /*open as usual*/;
fseek(fp, 0L, SEEK_END);
size_t fileSize = ftell(fp);

但是,这将返回文件中的字节数,而不是字符数。除非已知编码是每个字符一个字节(例如 ASCII),否则它是不一样的。

了解大小后,您需要将文件“倒回”到开头:

fseek(fp, 0L, SEEK_SET);
于 2012-02-03T16:47:00.207 回答
2

简单回答是不。更准确地说,它取决于系统:在 Unix 下,这是可能的(例如使用stat);在 Windows 下,文本文件是不可能的,但是如果你正在读取二进制文件,那么有一个GetFileSize可以使用的函数。

虽然不能保证,但在我知道的所有实现下(对于这两个平台),寻找文件末尾,然后执行 ftell,将返回一些东西,当转换为足够大的整数类型时,将给出相同的结果以上(具有相同的限制)。

最后:为什么需要这些信息?如果只是分配一个适当大小的缓冲区,即使是文本文件,GetFileSize(并且 tell在搜索到最后)将返回一个略大于您可以读取的字节数的值。您的缓冲区会稍微过大,但这通常不是问题。

于 2012-02-03T16:49:28.797 回答
1

我认为您可能正在寻找动态内存解决方案。您实际问的是“有没有办法在不读取文件的情况下获取文件中的字符数?”。答案(假设每个字符一个字节)是肯定的,您可以使用stat调用来获取文件大小,而以字节为单位的文件大小是字符数。对于 UTF-8,答案是否定的,但让我们暂时把它放在一边,因为刚刚学习的计算机科学家通常不担心国际化。

我认为你想知道有多少个字符的原因是你可以有足够大的存储空间来容纳它们。您不需要知道文件有多大就可以存储整个内容。

如果你有一个std::vector<char>,它开始可以容纳十个字符,然后增长到容纳二十个,然后是一万个......当你读完文件时,它会容纳所有的,即使你不知道有多少那里将会是。

于 2012-02-03T16:46:49.623 回答
1

我的头顶是看一下文件大小,然后将其除以单个字符的字节数?

处理空白和结束行等时会出现问题。

于 2012-02-03T16:47:38.827 回答