【问题标题】:C++ ifstream::read confusionC++ ifstream::read 混淆
【发布时间】:2019-08-19 15:50:10
【问题描述】:

我想遍历文件流的字节。 我正在使用 ifstream 类。当您使用 read 函数时,它会将字符从流中复制到我在参数列表中指定的数组中。我有 3 个问题。

int length = 1024;
char buff[1024];
ifstream inf(fp, ios::in | ios::binary);
inf.read(buff, length);

我之所以不需要在“buff”之前使用“&”是因为第一个参数不是指针而是引用?

如果我有这个怎么办:

int length = 1024;
vector<char> buffer;
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

它实际上做的是它获取向量第一个元素的内存地址。 只有第一个的地址! 但它仍然可以访问整个数组,因为它将字符复制到其中。这怎么可能? 同样的事情是否也适用于以下内容?:

int length = 1024;
char* buffer[1024];
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

这里,如何访问数组元素?

【问题讨论】:

  • A std::vector 保证所有元素在内存中一个接一个(就像数组元素一样)。这就是知道第一个地址和计数足以填充向量的原因。

标签: c++ arrays pointers reference implicit-conversion


【解决方案1】:

向量和数组将它们的数据保存在连续内存中,因此第二个元素紧跟在第一个元素之后等等。所以访问整个数组/向量所需的只是指向第一个元素和数组/向量的长度。

顺便说一句,这段代码是错误的

int length = 1024;
vector<char> buff;
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

因为向量buff 的大小为零,因此没有空间读取数据。如果你这样写就好了

int length = 1024;
vector<char> buff(length);
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

或者最好还是这样(因为我们使用size 方法查询向量以查看它有多大)

int length = 1024;
vector<char> buff(length);
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], buff.size());

甚至像这样更好(因为我们使用自描述的data 方法来获取指向向量数据的指针)。

int length = 1024;
vector<char> buff(length);
ifstream inf(fp, ios::in | ios::binary);
inf.read(buff.data(), buff.size());

【讨论】:

  • 谢谢,但是当您传递第一个元素的内存地址时,该函数将如何访问数组的其他元素?
  • @PatrikNusszer 因为根据定义,向量将其数据保存在连续内存中,因此第二个字节紧跟在第一个字节之后,依此类推。向量和数组在这方面是相同的。
  • 好的,那么请将该评论放入答案中,因为这是我问题的关键部分,对于新手来说并非易事
【解决方案2】:

成员函数read的声明方式如下

basic_istream<charT, traits>& read(char_type* s, streamsize n);

它的第一个参数是指针类型。

在本次通话中

inf.read(buff, length);

数组 buff 被编译器隐式转换为指向其第一个元素的指针。

所以这个调用等价于调用

inf.read( &buff[0], length);

但最后一个需要更多的输入。

如果你会写

inf.read(&buff, length);

那么参数的类型将是char ( * )[1024],编译器会报错,因为参数的类型和参数的类型不同。

至于这段代码sn-p当使用向量而不是字符数组时。

int length = 1024;
vector<char> buffer;
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

那么它是无效的,因为向量是空的。

你应该改写

int length = 1024;
vector<char> buffer( length );
ifstream inf(fp, ios::in | ios::binary);
inf.read(&buff[0], length);

它实际上做的是它获取第一个内存地址 向量的元素。只有第一个的地址!但它仍然有 访问整个数组,因为它将字符复制到其中。 怎么可能?

函数的第二个参数指定第一个参数设置的内存地址多大。

函数可以声明为例如模板函数

template <size_t N>
basic_istream<charT, traits>& read( char_type ( &s )[N] );

但在这种情况下,您将无法将指针传递给动态分配的数组或数组的一部分。

【讨论】:

  • "函数的第二个参数指定第一个参数设置的内存大地址如何。"有错别字吗?另外,你能写一个更详细的解释吗?我无法重播清楚地理解那句话。
  • @PatrikNusszer 该函数有两个参数。第一个指定内存的地址,第二个参数指定它的大小。什么不清楚?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多