std::istream
原型istream& read (char* s, streamsize n)
应该通过调用istream::gcount()
获取实际读取的字节数,istream
的有效性可以从ios::good
知道。
我正在和我的一位同事讨论另一个流类的实现,我在那里说我可能会遵循这个设计;但是他说,不是让用户每次都打电话给 gcount ,而是可以像这样istream& read (char* s, streamsize n, size_t &bytes_read)
阅读原型,这样它就可以在一次通话中结束而前者是笨拙的。我无法捍卫std
的设计选择。 istream::read
背后的真正原理是什么?
答案 0 :(得分:4)
我认为这是因为C ++通常不强制每个人都不需要的接口。如果您需要read
接受某些人不关心的参数,那么它会导致额外的编码工作(声明一个额外的int作为参数传递)。无论客户端是否关心,它也始终保存读取的字节数(某些客户端可能只关心读取失败,如eof / fail位所示)。
使用单独的方法,您可以为界面分配可能需要或可能不需要的不同信息。
答案 1 :(得分:2)
尝试使用readsome命令,
streamsize readsome ( char* buf, streamsize num );
buf是你的缓冲区,num是你想要读取的字节数,当然最多是缓冲区中可用的字节数。
返回值是实际读取的字节数。
要将文件读到最后,您可以循环:
char buf[BUF_SIZE]
streamsize bytesRead;
do
{
bytesRead = instr.readsome( buf, BUF_SIZE );
// do stuff with the bytes you read, if any
} while ( bytesRead == BUF_SIZE );
答案 2 :(得分:0)
std::istream
有原型istream& read (char* s, streamsize n)
实际读取的字节数 应该通过电话来获得istream::gcount()
,也是有效性 可以从istream
知道ios::good
。
istream::read(char* s, streamsize n)
在NULL
的数组中读取大小为n
的无格式数据块(没有s
终止)。尽管s
是指向char
的指针,但您可以使用istream::read
来读取二进制数据。例如,您可以拥有一个istream
来保存双精度数组的值(假设字节顺序是正确的):
unsigned int count;
input.read(reinterpret_cast<char*>(&count), sizeof(count));
double* data = new double[count];
for (unsigned int i = 0; i < count; ++i)
input.read(reinterpret_cast<char*>(data[i]), sizeof(double));
istream::gcount()
返回上一次istream::read
调用中读取的字节数。在这种情况下,我们发现count
的大小可能与double
的大小不同,因此我们无法使用istream::gcount()
来指定第一个元素的大小在data
数组中。
答案 3 :(得分:0)
在回答最初的问题时,当C年轻时,有错误检查电话是一种流行的编程风格,但很快就失去了时尚。会发生什么事情并不是非常错误,但是在他们被社区召唤并被标记为糟糕的情况之前,他们几乎总是存在一段时间。这段代码不幸之前已经被广泛讨论过的小反模式。
为了回应Cash Cow的解决方案,我认为存在一个错误。如果您正在等待IO并且有足够的字符来部分填充缓冲区,则该函数将返回并且while循环将在文件完全读取之前结束。因此,如果直接写入原始IO,他的解决方案可能会正确运行,但无法在缓冲IO上运行。
当然,正确的解决方案是在设置EOF标志时结束while循环。目前我不确定什么是badbit设置时的最佳响应,但你也应该处理这种情况。
我同意readome是一个不错的替代阅读。
编辑: 有时readome不可用(一些VC ++版本)。在这种情况下,读取不可用。