使用数学表达式拆分字符串

Split String with math expression

本文关键字:拆分 字符串 表达式      更新时间:2023-10-16

在将运算分配给数学运算符后,如何将字符串拆分为两部分?例如4567*6789我想把字符串分成三部分第一个:4567操作:*第二个:6789输入来自文本文件

char operation;
while (getline(ifs, line)){
stringstream ss(line.c_str());
char str;
//get string from stringstream
//delimiter here + - * / to split string to two part
while (ss >> str) {
if (ispunct(str)) {
operation = str;
}
}
}

也许,只是也许,通过思考这个问题,我们可以想出一个解决方案。

我们知道operator>>在遇到非数字字符时会停止处理。所以我们可以利用这个事实。

int multiplier = 0;
ss >> multiplier;

接下来的字符不是数字,所以它们可能是运算符字符
如果我们读入一个字符会发生什么:

char operation = '?';
ss >> operation;

哦,我忘了提一下operator>>默认情况下会跳过空格。

最后,我们可以输入第二个数字:

int multiplicand = 0;
ss >> multiplicand;

为了确认,让我们打印出我们在中读到的内容

std::cout << "First Number: " << multiplier << "n";
std::cout << "Operation   : " << operation << "n";
std::cout << "Second Number: " << multiplicand << "n";

在这里使用调试器将有助于在每次执行一条语句时显示正在发生的事情。

编辑1:更复杂
您总是可以变得更复杂,并使用解析器lexer或编写自己的解析器。一个好的实现方法是使用状态机。

例如,您将读取一个字符,然后根据状态决定如何处理它。例如,如果字符是一个数字,则可能需要生成一个数字。对于字符(空白除外),将其转换为标记并将其存储在某个位置。

有解析树和其他数据结构可以简化解析操作。还有一些解析库,比如boost::spirit、yacc、bison、flex和lex。

一种方法是:

char opr;
int firstNumber, SecondNumber;
ss>>firstNumber>>opr>>SecondNumber;

而不是:

while (ss >> str) {
if (ispunct(str)) {
operation = str;
}
}

或者使用正则表达式进行复杂的表达式。下面是一个在数学表达式中使用正则表达式的示例。

如果手头有一个字符串,您可以简单地在运算符位置将字符串分为左右两部分,如下所示:

char* linePtr = strdup("4567*6789");  // strdup to preserve original value
char* op = strpbrk(linePtr, "+-*");
if (op) {
string opStr(op,1);
*op = 0x0;
string lhs(linePtr);
string rhs(op+1);
cout << lhs << " " << opStr << " " << rhs;
}

一个简单的解决方案是使用sscanf:

int left, right;
char o;
if (sscanf("4567*6789", "%d%c%d", &left, &o, &right) == 3) {
// scan valid...
cout << left << " " << o << " " << right;
}

我的提议是创建函数:

std::size_t delimiter_pos(const std::string line)
{
std::size_t found = std::string::npos;
(found = line.find('+')) != std::string::npos ||
(found = line.find('-')) != std::string::npos ||
(found = line.find('*')) != std::string::npos ||
(found = line.find('/')) != std::string::npos;
return found;
}

第二个计算操作数的函数:

void parse(const std::string line)
{
std::string line;
std::size_t pos = delimiter_pos(line);
if (pos != std::string::npos)
{
std::string first = line.substr(0, pos);
char operation = line[pos];
std::string second = line.substr(pos + 1, line.size() - (pos + 1));
}
}

我希望我的例子能帮助你