输入错误:拆分一个条目的一部分
input errors : split part of one entery
我正在做一些标准练习 I/O
我有一个复杂的 class 。我的 class 有重载的插入和提取运算符,输入应为以下形式:
x + yi(例如 10 + 9i)
我必须确定输入是否有效。
有问题,如果我以这种形式输入,结果总是失败,
因为我正在将 char 'i' 输入到整数数据类型。
那么我如何做到这一点,而不会出现故障位?
我的功能是这样的:
istream &operator>>(istream &input, Complex &complex)
{
input >> complex.realPart;
input.ignore(3);
input >> complex.imaginaryPart;
return input;
}
但这显然是不够的!如果在 i 和整数之间有一个 space 它可以解决所有问题。但是没有!我想过使用数组,甚至字符串,但是然后将它们复制到我的 class 的 int 私有数据中,这似乎不是一个好的编程。毕竟我必须寻找什么错误?
多谢 ! ;)
您可以使用 std::getline
and 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
输出 - Live Demo
5 3
return value of std::sscanf
according to cppreference是
Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned.
所以你可以检查 return 值 == 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;
}
与之前版本的不同之处在于提供了另一个字母而不是加号:第一个版本立即停止读取输入,知道它无论如何都是错误的,而第二个版本将继续使用流。
我正在做一些标准练习 I/O 我有一个复杂的 class 。我的 class 有重载的插入和提取运算符,输入应为以下形式: x + yi(例如 10 + 9i) 我必须确定输入是否有效。 有问题,如果我以这种形式输入,结果总是失败, 因为我正在将 char 'i' 输入到整数数据类型。 那么我如何做到这一点,而不会出现故障位? 我的功能是这样的:
istream &operator>>(istream &input, Complex &complex)
{
input >> complex.realPart;
input.ignore(3);
input >> complex.imaginaryPart;
return input;
}
但这显然是不够的!如果在 i 和整数之间有一个 space 它可以解决所有问题。但是没有!我想过使用数组,甚至字符串,但是然后将它们复制到我的 class 的 int 私有数据中,这似乎不是一个好的编程。毕竟我必须寻找什么错误? 多谢 ! ;)
您可以使用 std::getline
and 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
输出 - Live Demo
5 3
return value of std::sscanf
according to cppreference是
Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned.
所以你可以检查 return 值 == 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;
}
与之前版本的不同之处在于提供了另一个字母而不是加号:第一个版本立即停止读取输入,知道它无论如何都是错误的,而第二个版本将继续使用流。