c – 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不报告文件的大小,也不报告偏移量
从字节开始.它报告一个可以的令牌值
后来被用来寻找同一个地方,仅此而已.
(甚至不能保证你可以将类型转换为
积分型.)

至少根据语言规范:在实践中,
在Unix系统上,返回的值将是以字节为单位的偏移量
从文件的开头,在Windows下,它将是
打开文件的文件开头的偏移量
二进制模式.对于Windows(和大多数非Unix系统),在文本中
什么模式,没有直接和即时的映射
tellg返回以及必须读取的字节数
那个位置.在Windows下,您真正​​依赖的是
该值将不小于您拥有的字节数
阅读(在大多数情况下,不会太大,
虽然它可以多达两倍).

如果确切地知道您可以读取多少字节很重要,
可靠这样做的唯一方法是阅读.你应该
能够做到这样的事情:

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];

不应该编译:你已经将缓冲区声明为char *,
所以* buffer有char类型,而不是指针.鉴于什么
你似乎在做,你可能想要将缓冲区声明为
一个char **.但更好的解决方案是宣布它
作为std :: vector< char>&或者是std :: string&. (那样,你
不必返回大小,也不会泄漏内存
如果有例外.)

其次,最后的循环条件是错误的.如果你真的
想一次读一个角色,

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

应该做的伎俩.一个更好的解决方案可能是
读取数据块:

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

甚至:

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

编辑:我刚刚注意到第三个错误:如果你打不开
文件,你不告诉来电者.至少,你应该
将大小设置为0(但某种更精确的错误
处理可能更好).

上一篇:c – QtCreator中的相对路径


下一篇:c – 重复输入的文件流