我正在编写一个可以对复数进行操作的程序。我有一个名为ComplexNumber的类,其中包含重载运算符。我的程序以complex *operator* complex
的形式从文件中获取输入。因此,例如输入看起来像3+4i + 2+3i
。我写了我的>>运算符所以这很好。
当输入看起来像3i + 1+2i
时,会出现问题。我们必须验证输入,以便在复数缺失部分时起作用。它可以只是一个实数,也可以只是一个虚数。
ComplexNumber类中与此问题相关的函数如下:
ComplexNumber::ComplexNumber(double r,double i)
{
realNum = r;
imaginaryNum = i;
}
istream& operator>>(istream &input , ComplexNumber& other) //Overloaded >> operator
{
char filter = 0;
double r =0;
double i = 0;
input >> r >> i >> filter;
other.setR(r);
other.setI(i);
return input;
}
我在主要课程中输入的方式如下:
void input(ifstream &in)
{
ComplexNumber a,b;
in >> a;
in.get();
string op;
getline(in,op,' ');
in >> b;
cout << a << " " << op << " " << b << endl;
}
int main()
{
ifstream in("complex.txt");
if(!in) cout << "failed to open file." << endl;
while(!in.eof()){
input(in);
}
return 0;
}
为了让我的操作员工作,我需要在对象中将输入的缺失部分设置为0。因此,如果输入为3i
,则对象中的变量将为realNum = 0, imaginaryNum = 3
如何实现此目标?
如何检查线路上的输入以决定如何读入?目前,它期望复数对它既有实部也有想象部分。
我还写了一个重载的构造函数,用于复数只有其中一个部分的情况,但我不确定如何使用它。功能如下:
ComplexNumber::ComplexNumber(double in, string r_i) //Overloaded constructor
{
if(r_i == "r"){realNum = in; imaginaryNum = 0;}
else{imaginaryNum = in; realNum = 0;}
}
除了这个问题,我们还必须检查以确保输入没有无效字符,例如。 j or !
但我觉得如果我得到第一个问题的帮助,我可以使用给出的信息来解决第二个问题。
我意识到这可能不会以最好的方式措辞,我希望你能理解我想要实现的目标。我真的很感激任何帮助。感谢。
答案 0 :(得分:1)
通常情况下,我会使用状态机来执行此操作。以前从未使用过C ++流。有点比看上去更狡猾,但基本相同。关于在代码中作为注释嵌入的最新和什么的评论。
#include <string>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cctype>
// Made this really dumb for ease of writing example
struct ComplexNumber
{
double realNum;
double imaginaryNum;
};
// splitting the guts of the parsing off into its own function made writing
// operator>> dead easy
bool parsecomplex(std::istream &input,
double & real,
double & imag)
{
char filter;
double temp;
char next;
if (input >> temp)// read a double. No clue if it's the real or imaginary part yet.
{
next = input.peek(); // check the next character, but do not extract
if (next != 'i') // not imaginary
{
real = temp; // store as real
if (next == '+' || next == '-') // do we stop here or is there an imaginary?
{
if (input >> imag >> filter // read imaginary
&& filter == 'i') // and ensure trailing i
{
return true;
}
}
else
{
return true;
}
}
else
{ // just an imaginary
imag = temp;
input >> filter; // remove the i. we already know it's an i
return true;
}
}
return false;
}
std::istream& operator>>(std::istream &input,
ComplexNumber& other)
{
double real = 0.0;
double imag = 0.0;
if (parsecomplex(input, real, imag))
{ // OK so we got a good complex number.
other.realNum = real;
other.imaginaryNum = imag;
input.clear(); // may have read eof
return input;
/* This next bit is a deviation from normal stream parsing. Typically 3j
would be read and store of 3 as real and j stays in the stream for the
next read. OP sounds like they might need to be a bit more anal. If so,
replace the above with
char next = input.peek();
if (std::isspace(next) || next == std::char_traits<char>::eof())
{
other.realNum = real;
other.imaginaryNum = imag;
input.clear(); // may have read eof
return input;
}
The Law of Least Surprise says you should go with the expected parsing
behaviour so as to not leave a trail of confused and angry programmers
in your wake. */
}
input.setstate(std::ios::failbit);
return input;
}
// quick test harness
void test(const char * str)
{
ComplexNumber cnum;
std::stringstream input(str);
if (input >> cnum)
{
std::string remaining;
std::getline(input, remaining);
std::cout << str << " is " << cnum.realNum <<","<< cnum.imaginaryNum
<< " still in stream: " << remaining << std::endl;
}
else
{
std::cout << "Invalid: " << str << std::endl;
}
}
int main()
{
test("3-3i");
test("3");
test("-3i");
test(" 3-3i");
test("3-3i ");
test("3 ");
test("-3i ");
test("3-3i 3-3i");
test("3 -3i");
test("j3+3i");
test("3j3i");
test("3+3j");
test("3+3ij");
test("3j");
test("-3j");
test("-3ij");
test("");
test("DETHTONGUE!");
}
输出:
3-3i is 3,-3 still in stream:
3 is 3,0 still in stream:
-3i is 0,-3 still in stream:
3-3i is 3,-3 still in stream:
3-3i is 3,-3 still in stream:
3 is 3,0 still in stream:
-3i is 0,-3 still in stream:
3-3i 3-3i is 3,-3 still in stream: 3-3i
3 -3i is 3,0 still in stream: -3i
Invalid: j3+3i
3j3i is 3,0 still in stream: j3i
Invalid: 3+3j
3+3ij is 3,3 still in stream: j
3j is 3,0 still in stream: j
-3j is -3,0 still in stream: j
-3ij is 0,-3 still in stream: j
Invalid:
Invalid: DETHTONGUE!