gpt4 book ai didi

c++ - 从字符串中解析复数,考虑语法变化

转载 作者:太空宇宙 更新时间:2023-11-04 12:40:28 24 4
gpt4 key购买 nike

我正在制作一个控制台应用程序,我可以在其中输入复数。一切正常,但我希望输入格式更加灵活。现在它只接受 a+bi,我想这样做,如果我只输入 3 或 -2i,它仍然有效。

Complex console::parseComplex(std::string cmp) { 
float a, b;
char i;
std::stringstream ss(cmp);
if (ss >> a >> b >> i && i == 'i')
return { a, b };
else return { true };

据我所知,如果我添加以下内容

    else if (ss >> a >> i && i == '\0')
return { a, 0 };
else if (ss >> b >> i && i == 'i')
return { 0, i };

在我的最后一行之前,它不会工作,因为 >> 通过 ss。字符串中不会有任何空格。我不确定如何在不重铸 ss 的情况下更改它(我认为这不是最好的方法)

而且我不确定如何过滤掉任何被转换为整数的随机字符并发送出去,检查 '\0' 感觉不对。

谢谢!

(顺便说一句,return {true} 会在被检查的类上转到 m_fail,这是我能想到的最简单的错误处理方法,但我是新手,所以如果你有任何关于该主题的文档我想阅读更多)

最佳答案

我已经建议编写一个小型解析器(例如,基于 SO: How to rearrange a string equation? 中所示的语法图)。

下面我按照OP尝试的方式做了一个更简单的方法(没有画语法图)。

即我的助手类型 Complex 的输入流运算符尝试读取两个数字。

如果第一个数字后跟一个 i 这实际上是第二个数字并且输入结束。

如果第二个数字后面没有跟 i 它实际上不是第二个但丢失了,流将重置到之前的位置。

示例代码:

#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>

struct Complex {
float re, im;
};

std::istream& operator >> (std::istream &in, Complex &value)
{
value.im = 0;
// read 1st value
if (!(in >> value.re)) return in; // ERROR!
// check whether next char is 'i'
char c; if (!(in >> c)) return in; // End of Input
if (c == 'i') {
value.im = value.re; value.re = 0.0;
return in;
}
in.unget();
// remember start of imaginary
std::streampos pos = in.tellg();
if (!(in >> value.im)) return in; // ERROR or end of input
if (!(in >> c) || c != 'i') { // ERROR or premature end of input
value.im = 0.0;
in.clear();
in.seekg(pos);
return in;
}
return in;
}

std::ostream& operator << (std::ostream &out, const Complex &value)
{
return out << value.re << (std::signbit(value.im) ? "" : "+") << value.im << 'i';
}

int main()
{
// samples:
std::string samples[] = {
"1.23+45i",
" 1.23 +45i",
" 1.23E3 +45e-1i",
"Completely wrong!",
// multiple numbers in one line
"1.23+45i 1.23 +45i 1.23E3 +45e-1i",
"1.23 2.34-1i -2i"
};
int line = 1;
for (const std::string &sample : samples) {
std::cout << "Parse line " << line++ << " '" << sample << "':\n";
std::istringstream in(sample);
std::cout << "Got:";
Complex value;
while (in >> std::skipws >> value) std::cout << ' ' << value;
std::cout << '\n'
<< "Stopped with "
<< (in.eof() ? "End of Input" : !in.good() ? "Error" : "???")
<< '\n';
}
return 0;
}

编译和测试:

g++ (GCC) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Parse line 1 '1.23+45i':
Got: 1.23+45i
Stopped with End of Input
Parse line 2 ' 1.23 +45i':
Got: 1.23+45i
Stopped with End of Input
Parse line 3 ' 1.23E3 +45e-1i':
Got: 1230+4.5i
Stopped with End of Input
Parse line 4 'Completely wrong!':
Got:
Stopped with Error
Parse line 5 '1.23+45i 1.23 +45i 1.23E3 +45e-1i':
Got: 1.23+45i 1.23+45i 1230+4.5i
Stopped with End of Input
Parse line 6 '1.23 2.34-1i -2i':
Got: 1.23+0i 2.34-1i 0-2i
Stopped with End of Input

Live Demo on coliru

虽然摆弄我仍然意识到一些弱点,例如1.23 + 45i 无法读取,因为 +45 之间有空格。所以,有了更多的代码,这肯定会得到改进。另一方面...... OP 没有具体说明哪里应该接受空格,哪里不接受空格。

关于c++ - 从字符串中解析复数,考虑语法变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54413316/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com