我正在尝试读取一个应该是以下形式的序列: 变量 运算符 变量 运算符 变量。 。 。依此类推,其中'变量'包含A,B或C,'运算符'是四个基本运算符之一+ - / *,如果符合给定形式则只打印有效,如果符合,则无效没有。此外,条件是序列必须以单个变量开始,并由操作员遵循(中间允许空格)。
我已经编写了一些代码来获取字符串输入,并且只有一个名为'check'的函数来查看它是否返回false,使程序打印为'Invalid'。这是我的主要功能:
using namespace std;
int main() {
string m;
cout<<"Please enter a sequence: "<<endl;
getline(cin,m);
bool allow = check(m);
if(allow == true){
cout<<"\n\nCorrect format "<<endl;
}
else{
cout<<"\n\nIncorrect format \n"<<endl;
}
system("PAUSE");
return 0;
}
这是我的检查功能:
bool check(string mi){
int c=0; //using c as an index,
mi.append("0"); //append a 0 as a signal to when the string ends
while(c < mi.length()){
if(mi.at(c)=='0'){}
else if(isblank(mi.at(c))){} //So it will accept spaces between the input
else if(mi.at(c) == 'A' ||mi.at(c) == 'B' ||mi.at(c) == 'C'){
//The sequence must start with a variable...
c +=1; //increment to start at the next character...
while(c < mi.length()){ //This whole loop is to check if the next
//significant character is one of the operators
if(isblank(mi.at(c))){}
else if(mi.at(c) !='+' ||mi.at(c) != '-' ||mi.at(c) != '/' || mi.at(c) != '*' || mi.at(c) !='0'){
cout<<"\n(Log) Character at "<<c<<" was not an operator? Value: "<<mi.at(c);
//Why does it always come here even if the value was an operator?
return false;
}
c++;
}
}
c++;
}
return true; //Assume true if there are no errors...
}
即使我输入了正确的序列,比如说A + B + C,它仍然是无效的。我已经将问题追溯到上面的特定代码行。为什么这样做?
答案 0 :(得分:3)
因为你的布尔逻辑不正确。
表达式:
mi.at(c) !='+' || mi.at(c) != '-' || mi.at(c) != '/' || mi.at(c) != '*' || mi.at(c) !='0'
每次评估为真。例如,如果mi.at(c)是&#39; - &#39;,那么mi.at(c)!=&#39; +&#39;评估为真,你进入你不想进入的那部分代码。同样,如果i.at(c)是&#39; +&#39;那么mi.at(c)!=&#39; - &#39;评估为真,再次将条件评估为真。
我相信你想把你的布尔或者(||)改为布尔和&#39;(&amp;&amp;)。
对于一些未经请求的建议,我个人建议花点时间将问题视为状态机。这将使您能够以可支持和可扩展的方式清理和思考它正在做什么。我不是一个c ++编码器,但这里是我如何在c作为状态机来处理它。您应该能够将其翻译为c ++:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main() {
char* VARS = "ABC";
char* OPS = "+-/*";
char c = EOF;
int state = 0;
while (((c = getchar()) != EOF) && (state < 3)) {
// move on to next character if we have a blank or end-of-line
if (c == ' ' || c == '\n')
continue;
// test to see if the character is a var or op
int isvars = (strchr(VARS, c) != NULL);
int isops = (strchr(OPS, c) != NULL);
// based upon character type and current state, determine next state
if (!isvars && !isops) // character is neither a valid var nor op
state = 3;
else if (isvars) // character is a var
if ((state == 0) || (state == 2))
state = 1;
else if (state == 1)
state = 3;
else if (isops) // character is an op
if ((state == 0) || (state == 2))
state = 3;
else if (state == 1)
state = 2;
}
puts((state > 1) ? "bad" : "good");
}
并且,这是将其编译为&#39; varop&#39;:
后的结果$ echo "" | ./varop
good
$ echo "A" | ./varop
good
$ echo "+" | ./varop
bad
$ echo "A+" | ./varop
bad
$ echo "AA" | ./varop
bad
$ echo "A+" | ./varop
bad
$ echo "A+A" | ./varop
good
$ echo "A++" | ./varop
bad
$ echo "A + B" | ./varop
good
$ echo " A + B" | ./varop
good
$ echo "D" | ./varop
bad
$ echo "%" | ./varop
bad
答案 1 :(得分:2)
你的问题在哪里是正确的,但问题是你的基本逻辑。由于您使用||
而非&&
,这意味着您的语句始终评估为true(即'+'将在第一个条件下评估为false
,但在检查不-
时将评估为true。您需要做的是将罪魁祸首行中的||
运算符替换为&&
,并且您的检查函数应该按预期运行。
另外,作为样式注释,在检查功能的第8行,而不是c += 1
,您应该使用c++
来保持一致性。
答案 2 :(得分:2)
试试这个,它会编译并提供所需的输出。但是,它仍然没有强制要求操作符后跟一个字符。但我想你可以搞清楚。
using namespace std;
为了提供帮助,我创建了一系列可能的运算符以及一个检查字符是否为运算符的函数。
unsigned char operators[] = { '+','-','/','*' };
bool isOperator(const unsigned char &m) {
for (int n = 0; n < 4; n++) if (m == operators[n]) return true;
return false;
}
在你的检查中只需要一个循环,for循环更加方便。注意逻辑,当角色是A或B或C或空白时我会继续。
bool check(string mi){
for (int c = 0; c < mi.size(); c++) {
cout << mi.at(c);
if (isblank(mi.at(c))) continue;
if (mi.at(c) == 'A' || mi.at(c) == 'B' || mi.at(c) == 'C') continue;
if (!isOperator(mi.at(c))) {
cout<<"\n(Log) Character at " << c <<" was not an operator? Value: "<<mi.at(c);
return false;
}
}
return true; //Assume true if there are no errors...
}
int main() {
string m;
cout<<"Please enter a sequence: "<<endl;
getline(cin,m);
cout << "\n\n" << string(check(m) ? "Correct":"Incorrect") << " format." << endl;
system("PAUSE");
return 0;
}
输出:
Please enter a sequence:
A+B+C
A+B+C
Correct format.
Press any key to continue . . .
答案 3 :(得分:0)
我建议您使用std::istringstream
并使用std::copy
将单独的组件转换为std::vector
个字符。然后迭代向量来检查只有有效的组件是很简单的。
为了帮助您使用std::copy
将组件放入向量中,建议您阅读std::istream_iterator
和std::back_inserter
。