【问题标题】:input errors : split part of one entery输入错误:拆分一个条目的一部分
【发布时间】:2015-08-29 13:22:17
【问题描述】:

我正在对标准 I/O 做一些练习 我有一个复杂的课程。我的班级重载了插入和提取运算符,输入应为: x + yi(例如 10 + 9i) 我必须确定输入是否有效。 有问题,如果我以这种形式输入结果总是一个失败位, 因为我正在将 char 'i' 输入到整数数据类型。 那么我怎么能做到这一点,而不会失败呢? 我的功能是这样的:

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

    return input;
}

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

【问题讨论】:

  • 不,复杂的没关系,I/O是我想学的,

标签: c++ input io


【解决方案1】:

您可以使用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是否是一个有效的输入

【讨论】:

  • 但是您将如何处理 cin &gt;&gt; c1 &gt;&gt; c2; 并将所有数据放在一行中? ;-)
  • 如果我仍然试图避免operator&gt;&gt;&lt;regex&gt; :)
  • 顺便重载operator&gt;&gt;是个好方法,我只是提供了一个替代方案,我也只是有点厚脸皮。
  • sscanf 很有意思,'%' 是为内置数据类型的第一个字符提供的?? "%f","%d","%c","%i" ?我想更多关于 sscanf 的细节,可以帮助回答!非常感谢,两个答案都很好,但第一个更接近我想要的!;)
  • 查看cppreference page上的表格。他们列举了每个代码是什么,例如%c%s
【解决方案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;
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-14
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多