我正在对标准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::getline
和std::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;
}
与先前版本的区别在于,当提供了除加号之外的另一个字母时:第一个版本立即停止读取输入,知道它无论如何都是错误的,而第二个版本将继续消耗流。