使用 cin.ignore() 提取整数期间的 C++ 奇怪输出

标签 c++

以下程序需要用户以混合分数格式“whole_numbernumerator/denominator”输入并将值分配给各个变量。

#include<iostream>
using namespace std;

int main()
{
    int whole, numerator, denominator;

    cout << "Input format: i<space>n/d" << endl;

    cin >> whole;
    cin.ignore(1000, ' ');
    cin >> numerator;
    cin.ignore(1000, '/');
    cin >> denominator;

    cout << whole << endl;
    cout << numerator << endl;
    cout << denominator << endl;

    return 0;
}

输入1:
123 345/678
输出1:
123
345
678

输入2:
1111111111 1111111111/1111111111
输出2:
1111111111
1111111111
1111111111

输入3:
2222222222 2222222222/222222222
输出3:
2147483647
0
0

我无法弄清楚为什么该程序不适用于 Input3。

最佳答案

您溢出了 32 位整数的最大值 (2^31-1 ~= 2.147b)。一旦发生这种情况,cin 将无法正常工作,直到您清除该标志。您应该检查错误,但短期解决方案是使您的数字无符号,或使用 64 位数字,如 int64_t。您也不需要忽略空格,因为 cin 默认会跳过它。

您可以实现类似于找到的东西 here以确保有效输入,但需要对其进行定制以适合您的特定输入格式。也许用一个重载运算符将这三个封装到一个类型中,该运算符根据格式输入每个运算符会使语法更合适,因此您可以将示例中的 age 替换为 MixedNumber 对象。

我认为这是一种通用的方法:

template <typename T> //any type will work
void getValidInput (T &var, std::string prompt = "Input: ") {
    while ((std::cout << prompt) && !(std::cin >> var)) { //if cin fails...
        std::cin.clear();                 //clear flag and discard bad input
        std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Invalid input; please re-enter.\n"; //let the user know
    } 
}

那么你的程序可以如下所示:

struct MixedNumber { //a data structure, so it's like using plain variables
    int64_t whole; 
    int64_t numerator;
    int64_t denominator;
};

std::istream &operator>> (std::istream &in, MixedNumber &num) { //so cin works
    in >> num.whole >> num.numerator;
    in.ignore(); //yes, you could enforce the format a bit more
    in >> num.denominator;
    return in;
}

int main() {
    MixedNumber num; //easy to "make" a mixed number, a constructor works well too
    getValidInput (num, "Input format: i<space>n/d: "); 
    std::cout << num.whole << '\n' << num.numerator << '\n' << num.denominator;
}

关于使用 cin.ignore() 提取整数期间的 C++ 奇怪输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11043863/

相关文章:

c++ - .net 中的私有(private)成员?

c++ - 升压条件需要可变变量

c++ - 使用 IOCTL_MOUNTMGR_QUERY_POINTS

c++ - C++ 代码中的参数不匹配错误

c++ - sstream 重新声明公共(public)访问编译器错误

c++ - 可以复制/复制 CCLayer 吗?

c++ - Visual Studio 2015 : C++ code analysis error C1253, 无法加载模型文件 'res://mspft140.dll/300'

c++ - Visual Studio 和 Visual C++ 一样吗

c# - 将只运行一次的代码移动到函数中是否可以?

c++ - MFC-CArray 复制