【问题标题】:Default value for variable in C++ using cin >>使用 cin 的 C++ 中变量的默认值 >>
【发布时间】:2015-11-04 10:48:08
【问题描述】:

我已经在 CodeBlocks IDE 中用 C++ 编写了这段代码,但是当我运行它时,如果它没有读取数字,它不会给我 -1,它给我 0。代码有问题吗?

#include "iostream"

using namespace std;

int main()
{
    cout<<"Please enter your first name and age:\n";
    string first_name="???"; //string variable
                            //("???" means "don't know the name")
    int age=-1; //integer variable (-1 means "don't know the age")
    cin>>first_name>>age; //read a string followed by an integer
    cout<<"Hello, " <<first_name<<" (age "<<age<<")\n";

    return 0;
}

【问题讨论】:

  • operator&lt;&lt;() 会将age 设置为其默认值(即在这种情况下为0)并在无法读取数字时覆盖-1。这是正常行为。
  • @πάνταῥεῖ 你的意思是operator&gt;&gt;,对吧?
  • en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt 引用:since c++11: If extraction fails, zero is written to value and failbit is set
  • 但是,从一开始,我就说age=-1,如果它没有读取任何内容,它应该输出-1。不应该吗? @πάνταῥεῖ
  • @Angew 哎呀,当然。

标签: c++ c++11


【解决方案1】:

std::basic_istream::operator>> 的行为已从 C++11 更改。从 C++11 开始,

如果提取失败,则将零写入 value 并设置 failbit。如果 提取导致值太大或太小而无法适应 值,std::numeric_limits::max() 或 std::numeric_limits::min() 已写入并设置了故障位标志。

请注意,直到 C++11,

如果提取失败(例如,如果在数字所在的位置输入了字母 预期),值保持不变并设置故障位。

您可以通过std::basic_ios::failstd::basic_ios::operator!查看结果并自行设置默认值。比如,

string first_name;
if (!(cin>>first_name)) {
    first_name = "???";
    cin.clear(); //Reset stream state after failure
}

int age;
if (!(cin>>age)) {
    age = -1;
    cin.clear(); //Reset stream state after failure
}

cout<<"Hello, " <<first_name<<" (age "<<age<<")\n";

另请参阅:Resetting the State of a Stream

【讨论】:

  • 我将向 OP 介绍如何检查故障位(然后设置默认值)。我也会指点他here: Resetting the State of a Stream
  • 我认为 OP 在这种情况下对设置默认值更感兴趣。 (而且我还会重置流的状态)
  • 谁是 OP?为什么当我让我的一个朋友在 Visual Studio 2015 中编写完全相同的代码时,如果它没有读取数字,它会给他-1?与IDE有关吗? @宋元瑶
  • @Alberto Original Poster - 问题的作者。 Visual Studio 在遵循标准方面通常很草率。他们的标准库很可能在这方面仍然遵循 C++03 的行为。
  • @Alberto 正如 Angew 所说,VS2015 可能还不支持这个 c++11 特性,或者你需要指定一些编译选项来启用它。无论如何,如果您检查输入结果并自己设置默认值(如我的答案中的代码),无论编译器是否支持该功能,它都会很好地工作。
【解决方案2】:

std::cin 读取时不支持自定义默认值。您必须将用户输入作为字符串读取并检查它是否为空。详情请见this question

引用链接的问题:

int age = -1;
std::string input;
std::getline( std::cin, input );
if ( !input.empty() ) {
    std::istringstream stream( input );
    stream >> age;
}

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 2012-03-30
    • 2011-02-08
    • 2011-09-22
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多