【问题标题】:testing an istream object测试 istream 对象
【发布时间】:2016-12-14 13:31:00
【问题描述】:

当我在测试中使用 std::istream 对象(以下示例中来自 cplusplus.com 的 std::ifstream)时:“if (myistreamobject)”,堆栈中自动分配的对象是永远不会为空,对吗?...在​​下面的示例中,我们使用相同的测试来检查是否从文件中读取了所有字节...这确实是一个奇怪的代码,我通常在处理时使用这种样式用指针...

我想知道 std::istream 中使用哪种机制在测试中返回一个值,以及该值的真正含义...(最后一次操作的成功/失败??) bool cast(如 MFC 类 CString 中的 const char* 运算符)还是另一种技术?

因为对象永远不会为空,所以将其放入测试中将始终返回 true。

// read a file into memory
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream

int main () {

  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    char * buffer = new char [length];

    std::cout << "Reading " << length << " characters... ";
    // read data as a block:
    is.read (buffer,length);

    if (is) // <== this is really odd
      std::cout << "all characters read successfully.";
    else
      std::cout << "error: only " << is.gcount() << " could be read";
    is.close();

    // ...buffer contains the entire file...

    delete[] buffer;
  }
  return 0;
}

【问题讨论】:

标签: c++ iostream istream


【解决方案1】:

operator bool() 

如果流没有错误则返回true,否则返回false。

无错误”的概念与之前对流本身进行的操作有关。

例如:在你调用构造函数之后

std::ifstream is ("test.txt", std::ifstream::binary);

设置了流对象中的内部状态标志。因此,当您调用运算符 bool 时,您会检查构造操作是否失败。

还有方法

is.read(...)

还设置此内部状态标志,如您在reference 中所见:

通过修改内部状态标志来发出错误信号:eofbitfailbitbadbit

所以在方法调用之后,如果流到达 EOF(文件结尾),则设置状态位,运算符 bool 将返回一个正值。

这意味着在这种情况下,当您使用

测试流时
if (is) { ... }

并且设置状态位,然后将验证条件并采用if-branch。

【讨论】:

    【解决方案2】:
    if (expression)
    

    对其进行测试 expression 评估为 true 这是一个布尔值。它适用于指针,因为nullptr/NULL/0 评估为false,其他一切true。出于同样的原因,它适用于整数值。

    对于一个对象,它属于operator bool(),参见http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool

    检查流是否没有错误。

    1) 如果 fail() 返回 true,则返回空指针,否则返回非空指针。此指针可隐式转换为 bool,并可在布尔上下文中使用。

    2) 如果流没有错误并且准备好进行 I/O 操作,则返回 true。具体来说,返回 !fail()。

    这个操作符可以使用返回对流的引用作为循环条件的流和函数,从而产生惯用的 C++ 输入循环,例如 while(stream >> value) {...} 或 while(getline(stream,字符串)){...}。

    只有当输入操作成功时,这样的循环才会执行循环体。

    【讨论】:

      【解决方案3】:

      std::istream 有运营商声明正确: explicit operator bool() const;

      当你写作时 if(SomeStdIstremObject) { ... } 真的是在调用 if(SomeStdIstreamObject.operator bool()) 不检查非零

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-18
        • 2014-05-15
        • 2010-10-12
        相关资源
        最近更新 更多