输入错误:拆分一个肠道的一部分

时间:2015-06-13 17:34:41

标签: c++ input io

我在标准I / O上做一些练习 我有一个复杂的课程。我的类重载了插入和提取操作符,输入应该是以下形式: x + yi(例如10 + 9i) 我必须确定输入是否有效。 有问题,如果我输入这种形式,结果总是一个故障, 因为我正在输入一个字母'我'到整数数据类型。 所以我怎么能做到这一点,没有失败的位? 我的功能是这样的:

istream &operator>>(istream &input, Complex &complex)
{
    input >> complex.realPart;
    input.ignore(3);
    input >> complex.imaginaryPart;

    return input;
}

但这显然是不够的!如果i和整数之间有空格,它可以解决所有问题。但是没有!我想过使用数组,甚至是字符串,但是然后将它们复制到我的类的int私有数据中,似乎不是一个好的编程。毕竟我必须寻找什么错误? 非常感谢 ! ;)

2 个答案:

答案 0 :(得分:2)

您可以使用std::getlinestd::sscanf来解析值

#include <cstdio>
#include <iostream>
#include <string>

int main()
{
    std::string input;
    std::getline(std::cin, input);

    int real;
    int imaginary;
    std::sscanf(input.c_str(), "%i + %ii", &real, &imaginary);
    std::cout << real << " " << imaginary;
}

输入

5 + 3i

输出 - Live Demo

5 3

return value of std::sscanf according to cppreference

  

成功分配的接收参数数,如果在分配第一个接收参数之前发生读取失败,则为EOF。

因此,您可以检查返回值== 2是否确保它是有效输入

答案 1 :(得分:1)

你必须检查'+'和尾随'i':

istream &operator>>(istream &input, Complex &complex)
{
    char plus,letter;
    if (input >> complex.realPart >> plus)  {
        if (plus!='+' ) 
            input.setstate(ios::failbit);
        else if (input >> complex.imaginaryPart>>letter) {
             if (letter!='i')
                 input.setstate(ios::failbit);
        }
    }
    return input;
}

直播demo here

请注意,您也可以通过以下方式简化:

istream &operator>>(istream &input, Complex &complex)
{
    char plus,letter;
    if ( (input >> complex.realPart >> plus >> complex.imaginaryPart>>letter) && (plus!='+' || letter!='i'))
            input.setstate(ios::failbit);
    return input;
}

与之前版本的区别在于提供了另一个字母而不是加号:第一个版本立即停止读取输入,知道它无论如何都是错误的,而第二个版本将继续消耗流。