【问题标题】:Is it variable initialization failure?是变量初始化失败吗?
【发布时间】:2020-05-14 08:13:20
【问题描述】:

遵循 Bjarne Stroustrup 的“编程原理和使用 C++ 的实践”一书,从基础开始学习 C++。在这件事发生之前,这一切都证明是好的......

int main()
{
      cout << "Please enter your first name and age\n";
      string first_name = "???"; // string variable
      int age = -1; // integer variable
      cin >> first_name >> age; // read a string and then integer
      cout << "Hello, " << first_name << " (age " << age << ")\n";
}

现在,正如上面的代码 (在第 2 章的输入和类型部分) 所暗示的,它输出一个字符串,让我们熟悉 name一个人的年龄。由于我已将 整数变量 age 初始化为 -1,因此程序必须返回 -1 如果我在 age 中输入了一个 字符串值 以防万一。问题是它不会发生在我的电脑上。我已经尝试编译并运行了 19 次程序(我确实记得...),但结果始终相同:它输出 0 而不是 -1

例如如果我输入ABCXYZ 16,那么输出将是一个漂亮而简单的你好,ABCXYZ(16 岁)。但是如果输入是 16 ABCXYZ,那么输出结果是 Hello, ABCXYZ (age 0),我预计会是 Hello, ABCXYZ (age -1) 作为字符串ABCXYZ 不会被读入age(它是一个整数变量)和因此给出初始化值,因为它没有被覆盖。

有什么想法吗?

P.S.:我正在使用 Code:Blocks 和 GCC - 8.1.0

【问题讨论】:

  • 您正在阅读的版本是多少?这个细节在 c++11 中改变了。请考虑 rtfm(阅读精美手册)。例如这里:en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
  • 旧的行为在我看来总是更合乎逻辑。不知道为什么会改变。
  • 从您的问题中删除不必要的代码和文本。 int age = -1; std::cin&gt;&gt;age; std::cout&lt;&lt;age; 就足够了。
  • @john 同样在这里,我真的很困惑动机是什么。以前是 UB 而现在不再是 UB 的代码很可能仍然是错误的
  • @idclev463035818 上面写着第二版。封面提到这本书使用了 C++11 C++14

标签: c++ variables variable-initialization


【解决方案1】:

std::istream&amp; operator&gt;&gt;(int &amp;value) 在内部调用 std::num_get::get()。从 cppreference std::num_get::get() 开始,c++11 中的行为发生了变化。

v 表示我们读入的变量,直到 c++11 我们有:

  • 如果发生错误,v 保持不变。

但是从 c++11 开始:

  • 如果转换函数无法转换整个字段,则 值​0​存储在v中

  • 如果转换函数导致 正值或负值太大,不适合 v 的类型,即 一个有符号整数类型,最可表示的正数或负数 值分别存储在v中

  • 如果转换函数结果 在一个不适合 v 类型的值中,它是一个无符号整数 类型,最正的可表示值存储在v中。

您正在使用配置为与 c++11 之后的标准兼容的编译器和 C++ 标准库进行编译,因此当 std::cin 无法读取该字段时,0 的值将存储到 age

【讨论】:

  • 所以&gt;&gt;不能用?
【解决方案2】:

问题与&gt;&gt; 运算符隔离,它无法将您的字符串输入转换为整数(这是预期的,因为std::cin &gt;&gt; x 处理预期的输入,来自您为x 定义的类型),并且因此返回一个 0,不管你用什么值初始化整数变量。

正如 Kamil 提到的,这是自 C++ 11 以来完成的,并且符合以前的标准,该值将保持不变,并为您的情况返回 -1。

您可以检查cin是否失败或通过以自己得出结论:

int main() 
{
      int age = -1; 
      std::cin >> age;
      if(cin) 
      std::cout << age; 
}

如果你输入一个整数(正如age 的类型所期望的那样)你会得到你初始化它的年龄值的输出,否则如果你输入一个字符串,cin 将失败(并且它的失败位将被触发,结果为 false) 并且不会显示任何内容,按照上面的 if 语句。

【讨论】:

  • 对,cin 失败了。那么,正如@KamilCuk 所说,&gt;&gt; 运算符不能用于实现我提到的目的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多