c++字符串操作给我奇怪的/不一致的/错误的结果
C++ string operations giving me weird/inconsistent/wrong results
我正试图读取一个应该以以下形式出现的序列:<<strong>变量/strong> 操作符变量操作符变量。等等,其中"变量"由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<<"nnCorrect format "<<endl;
}
else{
cout<<"nnIncorrect 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,它仍然是无效的。我已经将问题追溯到上面的特定代码行。为什么会这样呢?
因为你的布尔逻辑不正确。
表达式:
mi.at(c) !='+' || mi.at(c) != '-' || mi.at(c) != '/' || mi.at(c) != '*' || mi.at(c) !='0'
每次都会计算为真。例如,如果mi.at(c)是'-',那么mi.at(c) != '+'的计算结果为true,并进入您不想进入的那部分代码。同样地,如果i.at(c)是一个'+',那么mi.at(c) != '-'的计算结果为真,你的条件计算结果再次为真。
我相信你想把你的布尔"或"(||)改成"与"(&&)。
对于一些未经请求的建议,我个人建议花点时间将问题视为状态机。这将使您能够以可支持和可扩展的方式清理并思考它正在做什么。我不是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");
}
并且,下面是编译为'varop'后的结果:
$ 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
你的问题是正确的,但问题是你的基本逻辑。因为您使用||
而不是&&
,这意味着您的语句将始终求值为真(即:在第一种情况下,"+"将计算为false
,但在检查非-
时将计算为true。您需要做的是将罪魁祸首行的||
操作符替换为&&
,然后您的检查函数应该按预期运行。
此外,作为样式说明,在检查函数的第8行,为了保持一致性,您应该使用c++
而不是c += 1
。
试一下,它会编译并给出所需的输出。但是,它仍然没有强制操作符后面必须跟一个字符。但是我想你能弄明白的。
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或为空时,i继续。
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 << "nn" << 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 . . .
我建议使用std::istringstream
和使用std::copy
将单独的组件转换为std::vector
的字符。然后很容易遍历vector,只检查有效的组件。
为了帮助使用std::copy
将组件放入矢量,我建议您阅读std::istream_iterator
和std::back_inserter
。
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 我在c ++矩阵计算器程序中找不到错误
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- DLL 注入不断失败,出现不一致的错误
- 元数据操作失败LNK2022错误 (8013118D):重复类型中的布局信息不一致 (选择设备参数):(0x020002
- C++的 istream::eof() 的不一致是规范中的错误还是实现中的错误?
- C++ 对指针的引用:不一致的段错误
- 形成两组的并集似乎给出了错误且不一致的答案
- OutputDebugString导致不一致的错误
- 字符串流错误不一致
- c++字符串操作给我奇怪的/不一致的/错误的结果
- 如何纠正不一致的未解决外部错误
- 运行时出现不一致的分段错误
- 收到错误:将我的 c++ 代码从 Linux 移植到 android 时'asm'中的操作数约束不一致