tellg()函数给出错误的文件大小?

我做了一个示例项目,将文件读入缓冲区。 当我使用tellg()函数时,它给了我一个比读取函数实际从文件中读取的值更大的值。 我认为有一个错误。

这里是我的代码:

编辑:

void read_file (const char* name, int *size , char*& buffer) { ifstream file; file.open(name,ios::in|ios::binary); *size = 0; if (file.is_open()) { // get length of file file.seekg(0,std::ios_base::end); int length = *size = file.tellg(); file.seekg(0,std::ios_base::beg); // allocate buffer in size of file buffer = new char[length]; // read file.read(buffer,length); cout << file.gcount() << endl; } file.close(); } 

主要:

  void main() { int size = 0; char* buffer = NULL; read_file("File.txt",&size,buffer); for (int i = 0; i < size; i++) cout << buffer[i]; cout << endl; } 

tellg不报告文件的大小,也不报告从字节开始的偏移量。 它报告一个令牌值,以后可以用来寻find同一个地方,只是没有更多。 (甚至不能保证你可以将types转换为整型。)

至less根据语言规范:实际上,在Unix系统中,返回的值将是从文件开头起的偏移量(以字节为单位),在Windows下,它将是文件开始处的偏移量,二进制模式 。 对于Windows(以及大多数非Unix系统),在文本模式下, tellg返回值和您必须读取的字节数之间没有直接和直接的映射。 在Windows下,所有你可以真正指望的是,这个值不会less于你必须读取的字节数(在大多数情况下,不会太多,尽pipe它可以多达两倍)。

如果确切地知道你可以读取多less字节是很重要的,那么可靠的唯一方法就是阅读。 你应该能够做到这一点,如:

 file.ignore( std::numeric_limits<std::streamsize>::max() ); std::streamsize length = file.gcount(); file.clear(); // Since ignore will have set eof. file.seekg( 0, std::ios_base::beg ); 

最后,另外两个关于你的代码的评论:

一,线路:

 *buffer = new char[length]; 

不应该编译:你已经声明bufferchar* ,所以*buffertypes是char ,而不是指针。 鉴于你似乎在做什么,你可能想要声明bufferchar** 。 但是更好的解决scheme是将其声明为std::vector<char>&std::string& 。 (这样,您不必返回大小,如果发生exception,也不会泄漏内存。)

其次,最后的循环条件是错误的。 如果你一次只想读一个字,

 while ( file.get( buffer[i] ) ) { ++ i; } 

应该做的伎俩。 更好的解决scheme可能是读取数据块:

 while ( file.read( buffer + i, N ) || file.gcount() != 0 ) { i += file.gcount(); } 

甚至:

 file.read( buffer, size ); size = file.gcount(); 

编辑:我只注意到第三个错误:如果你打不开文件,你不告诉调用者。 至less,你应该设置size为0(但某种更精确的error handling可能更好)。

 fseek(fptr, 0L, SEEK_END); filesz = ftell(fptr); 

将通过打开文件打开文件

使用ifstream,

 in.seekg(0,ifstream::end); dilesz = in.tellg(); 

会做类似的

 void read_file (int *size, char* name,char* buffer) *buffer = new char[length]; 

这些行看起来像一个bug:你创build一个char数组并保存到缓冲区[0]字符。 然后你读取一个文件缓冲,这仍然是未初始化的。

你需要通过指针传递buffer

 void read_file (int *size, char* name,char** buffer) *buffer = new char[length]; 

或者通过引用,这是c + +的方式,并且不太容易出错:

 void read_file (int *size, char* name,char*& buffer) buffer = new char[length]; ...