输入错误:拆分一个条目的一部分



我正在对标准I/O进行一些练习我有一个复杂的类.我的类有重载的插入和提取运算符,输入的形式应该是:x + yi(例如 10 + 9i)我必须确定输入是否有效.有一个问题,如果我以这种形式输入结果总是一个故障位,因为我正在将字符"i"输入到整数数据类型。那么我怎么能做到这一点,而不会出现故障?我的函数是这样的:

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

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

您可以使用

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

输出 - 现场演示

5 3

根据 cpp 首选项std::sscanf的返回值为

成功分配的接收参数

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

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

您必须检查"+"和尾随的"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;
}

现场演示在这里

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

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;
}

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

最新更新