balances brackets problem(always the output is good) - c++

I have to write a program which balances a string with brackets.I wrote the program but it doesn't matter which string I enter because the program always says that the string is good.
Here's the code:
header file
#ifndef HEADER_H_
#define HEADER_H_
#include <string>
struct Element {
char data;
Element* link;
};
typedef Element* Stack;
void initStack(Stack& S);
void push(Stack& S, int a);
void pop(Stack &S);
int top(Stack& S);
bool isEmpty(Stack &S);
bool goodPair(char deschis, char inchis);
bool check(std::string s);
#endif
functions file
#include <iostream>
#include <string>
#include "header.h"
using namespace std;
void initStack(Stack& S)
{
S = nullptr;
}
void push(Stack& S, int a)
{
Element*nou = new Element;
nou->data = a;
nou->link = S;
S = nou;
}
void pop(Stack& S)
{
Stack aux = S;
S = S->link;
delete(aux);
}
int top(Stack& S)
{
if (isEmpty(S))
return int();
return S->data;
}
bool isEmpty(Stack &S)
{
if (S == 0)
return true;
else
return false;
}
bool goodPair(char deschis, char inchis)
{
if (deschis == '(' && inchis == ')')
return true;
else if (deschis == '[' && inchis == ']')
return true;
else if (deschis == '{' && inchis == '}')
return true;
else if (deschis == '<' && inchis == '>')
return true;
else
return false;
}
bool check(std::string s)
{
Element* S;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(' || s[i] == '[' || s[i] == '{' || s[i] == '<')
push(S, s[i]);
else
{
if (s[i] == ')' || s[i] == ']' || s[i] == '}' || s[i] == '>')
if (isEmpty(S) || !goodPair(top(S), s[i]))
return false;
else
pop(S);
}
}
if (isEmpty(S))
return false;
else
return true;
}
main file
#include <iostream>
#include <string>
#include "header.h"
using namespace std;
int main()
{
Stack S;
initStack(S);
string s;
cout << "Write the string:";
cin >> s;
if (check(s))
cout << "Good";
else
cout << "Bad";
return 0;
}
I used a stack and I traversed each character.If the character is an opening bracket I put it in the stack.When the character is a closing bracket, I compare it with the top of the stack.If it's good I pop the top of the stack.

You create a pointer to Element (aliased as Stack) S in main() and initialize it with nullptr using initStack() and then you do not use this variable anymore. Instead you create a local S in function check() and use it uninialized, which leads to UB.
Looks like you get confused by naming as you call of them S (variable in main(), variable in check(), all reference parameters all called S). It is not illegal to do so, but looks like you confused yourself. (you even called std::string lowercase s to increase confusion)
Also you have logical error in your function:
if (isEmpty(S))
return false;
else
return true;
should be opposite, if stack is empty then string is balanced, not vice versa. So replace it with:
return isEmpty( S );

Related

What Does Expression: cannot dereference end list iterator mean?

I keep getting this error message on my code, its saying its on line 149, but there's nothing on line 149 and so I'm having trouble understanding what is wrong. Does anyone know?
Context - this is a simple balancing symbols checker program exercise
This is the error message after i type in the name of the file.
This is the full code:
#include <iostream>
#include <fstream>
#include <string>
#include<list>
using namespace std;
void openInputFile(ifstream& inFile);
template<class T>
class Stack {
list <T> data;
public:
Stack() : data() {}
void push(T newItem) { data.push_front(newItem); }
T pop() { T topVal = top(); data.pop_front();
return topVal; }
T top() const { return *data.begin(); }
bool isEmpty() const { return data.size() == 0; }
int size() const { return data.size(); }
void clear() { data.clear(); }
};
class brackets {
brackets() : bracket() {}
char bracket;
};
int main()
{
Stack<char> dataChecker;
ifstream inFile;
string charChecker;
char currChar;
int size;
bool goodToGo = true;
cout << "First enter the name of the data file,
then press enter. " << endl;
openInputFile(inFile);
while (getline(inFile, charChecker)) {
size = charChecker.size();
if (charChecker.find("begin") ||
charChecker.find("Begin") ||
charChecker.find("BEGIN")) {
dataChecker.push('b');
}
if (charChecker.find("end") ||
charChecker.find("End") ||
charChecker.find("END")) {
currChar = dataChecker.pop();
if (currChar != 'b') {
goodToGo = false;
break;
}
}
for (int i = 0; i < size; i+= 1) {
if ((charChecker[i] == '{') ||
(charChecker[i] == '}') ||
(charChecker[i] == '[') ||
(charChecker[i] == ']') ||
(charChecker[i] == '(') ||
(charChecker[i] == ')')) {
switch (charChecker[i]) {
case '{' :
dataChecker.push('{');
case '[':
dataChecker.push('[');
case '(':
dataChecker.push('(');
case '}':
currChar = dataChecker.pop();
if (currChar != '{') {
goodToGo = false;
break;
}
case ']':
currChar = dataChecker.pop();
if (currChar != '[') {
goodToGo = false;
break;
}
case ')':
currChar = dataChecker.pop();
if (currChar != '(') {
goodToGo = false;
break;
}
}
}
}
}
if (goodToGo == false) {
cout << "There is an error in the data." <<
endl;
}
else {
cout << "The data looks good!" << endl;
}
return 0;
}
void openInputFile(ifstream& inFile) {
cout << "Please enter a filename: ";
string filename;
cin >> filename;
inFile.open(filename);
while (!inFile) {
cout << "Bad file name";
cout << "Please enter a filename: ";
cin >> filename;
inFile.clear();
inFile.open(filename);
}
}
Looking into line 149 of file <list> (the dialog message gives you the full path, also right-click and open on #include <list> in the editor helps):
_NODISCARD reference operator*() const {
#if _ITERATOR_DEBUG_LEVEL == 2
const auto _Mycont = static_cast<const _Mylist*>(this->_Getcont());
_STL_ASSERT(_Mycont, "cannot dereference value-initialized list iterator");
_STL_VERIFY(this->_Ptr != _Mycont->_Myhead, "cannot dereference end list iterator");
#endif // _ITERATOR_DEBUG_LEVEL == 2
return this->_Ptr->_Myval;
}
So this is simple. You have a list iterator (for example iter) and call operator* on it (-> *iter). That is not allowed and the assertion is telling you that. When you run the program in a debugger and look at the call stack you can directly navigate to the code where you call *iter.
Maybe you are calling top or pop on an empty Stack?

Infix/Postfix evaluator terminating issue

I've got a few different functions that on their own work fine. Now I am trying to put them together into one file. My debugger is throwing segmentation faults in the infixToPostfix function.
When I watch the ns variable, it does not show anything getting assigned to it, but it prints out the postfix expression when I actually run the code. When ns passes into PostfixEvaulation, it runs to the top member function of TemplateStack and crashes with:
terminate called after throwing an instance of "std::string"
This only happens when I pass a string with an operator. When I pass a string of just numbers, everything runs fine,
but it still does not seem to call PostfixEvaluation.
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
using namespace std;
//Class Template Stack declaration
template <class T>
class TemplateStack {
public:
typedef T type;
TemplateStack()
{
max_size_ = 50;
TopOfStack = 0;
data_ = new T[max_size_];
} //Default Constructor taking no parameters
void push(T element)
{
if (TopOfStack == max_size_)
throw string("Stack's underlying storage is overflow");
TopOfStack++;
data_[TopOfStack] = element;
}
void pop() {
if (TopOfStack == -1)
throw string("Stack is empty");
TopOfStack--;
}
T top() {
if (TopOfStack == -1)
throw string("Stack is empty");
return data_[TopOfStack];
}
private:
int TopOfStack; //Generic data type for the top element of stack
size_t max_size_;
T* data_;
};
//Function to Evauluate the Postfix notation expresion
int PostfixEvaulation(string input){
//string input;
int operand1, operand2, result,number;
TemplateStack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
//cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
//Function to return precedence of operators
int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
//Function: Convert Infix to Postfix
void infixToPostfix(string s)
{
TemplateStack<char> st;
st.push('N');
int l = s.length();
string ns;
for (int i = 0; i < l; i++) {
// If the scanned character is an operand, add it to output string.
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
ns += s[i];
}
// If the scanned character is an ‘(‘, push it to the stack.
else if (s[i] == '(') {
st.push('(');
}
// If the scanned character is an ‘)’, pop and to output string from the stack
// until an ‘(‘ is encountered.
else if (s[i] == ')') {
while (st.top() != 'N' && st.top() != '(') {
char c = st.top();
st.pop();
ns += c;
}
if (st.top() == '(') {
char c = st.top();
st.pop();
}
}
//If an operator is scanned
else {
while (st.top() != 'N' && prec(s[i]) <= prec(st.top())) {
char c = st.top();
st.pop();
ns += c;
}
st.push(s[i]);
}
}
//Pop all the remaining elements from the stack
while (st.top() != 'N') {
char c = st.top();
st.pop();
ns += c;
}
cout << "Here is the ns variable: "<< ns << endl;
PostfixEvaulation(ns);//Call the PostFixEvaluationFunction with the ns (postfix notation) variab
}
//Function: User inputs Expression
void GetInput(){
string input;
cout << "Enter Infix Expression: ";
getline(cin, input);
infixToPostfix(input);
}
int main()
{
GetInput();
}

LNK2005 error, already defined in main.obj

So ive been writing my code for a bit now and im not the best coder in the world. im still learning and consider myself a beginner. im writing a lexical analysis for a concepts class in c++. Ive tried the solutions ive seen on websites like this such as using extern in the header file and using const in the cpp files, but noting works.when i include my header file in 2 separate .cpp files i get this error for all the ints in the header file:
tokens.obj : error LNK2005: "int eND" (?eND##3HA) already defined in main.obj
header file=
#include <string.h>
#include <map>
using namespace std;
extern int lANGLE=1, rANGLE=2,iD=3, eQ=4, sLASH=5, qSTRING=6, oTHER=7, eND=8, tEXT=9;
map <int, int> counter;
extern int getToken(istream *br, string& lexeme);
token.cpp(declaring what getToken does)
#include "suffix.h"
#include <iostream>
#include <fstream>
#include <map>
#include <cctype>
bool slash = false;
bool text = false;
bool quote = false;
bool id = false;
bool equ = false;
bool other = false;
bool qstring = false;
char prev=NULL;
int getToken(istream *in, string& lexeme)
{
char c;
char prev;
lexeme="";
int intSlash = 0;
int intText = 0;
int intQuote = 0;
int intId = 0;
int intEqual = 0;
int intOther = 0;
int intQstring = 0;
int langlec = 0;
int intLangle = 0;
int ranglec = 0;
int intRangle = 0;
if (in->eof())
return eND;
while (in->get(c))
{
switch (c)
{
case '/' :
if (quote == false && langlec > 0)
{
slash = true;
intSlash++;
return 5;
}
break;
case '=' :
if (quote == false && langlec > 0)
{
equ = true;
intEqual++;
return 4;
}
break;
case '<' :
if ( prev != ' ' && langlec == 0)
{intText++ ;
return 9;}
if (quote == false)
{
langlec ++;
intLangle ++;
id = true;
return 1;
}
break;
case '>' :
if (quote != true)
{
ranglec++;
intRangle++;
return 2;
if (langlec > 0)
{
langlec--;
id = false;
}
}
break;
case '"' :
if (langlec > 0 && quote == true)
{
quote = false;
id = true;
intQstring ++;
intOther--;
return 6;
}
else if (langlec > 0)
{
intOther++;
quote = true;
return 7;
}
break;
case ' ':
if ( prev != ' ' && prev != '<' && prev != '>' && quote == false){
if (langlec == 0){
intText++;
return 9;
}
}
else if ( prev != '/' && prev != '=')
{intId++;
return 3;
}
break;
default:
if (quote == true)
{
id = false;
}
else if (id==true)
{
intId++;
id=false;
return 3;
}
prev=c;
}
}
return 0;
}
main.cpp
#include <iostream>
#include <fstream>
#include <map>
#include <cctype>
#include <string>
#include <algorithm>
#include "suffix.h"
using namespace std;
int
main( int argc, char *argv[] )
{
istream *br;
ifstream infile;
// check args and open the file
if( argc == 1 )
br = &cin;
else if( argc != 2 ) {
cout<<"THERE IS A FATAL ERROR"<<endl;
return 1; // print an error msg
} else {
infile.open(argv[1]);
if( infile.is_open() )
br = &infile;
else {
cout << argv[1] << " can't be opened" << endl;
return 1;
}
}
string tokens="";
int typeOfToken;
while(true){
typeOfToken=getToken(br,tokens);
if (counter.count(typeOfToken))
counter[typeOfToken]+=1;
else
counter[typeOfToken]=1;
if(typeOfToken==8)
break;
}
cout<<"total token count: "<<endl;
if (counter[1]!=0)
cout<<"LANGLE: "<<counter[1]<<endl;
if (counter[2]!=0)
cout<<"RANGLE: "<<counter[2]<<endl;
if (counter[9]!=0)
cout<<"TEXT: "<<counter[9]<<endl;
if (counter[3]!=0)
cout<<"ID: "<<counter[3]<<endl;
if (counter[4]!=0)
cout<<"EQ: "<<counter[4]<<endl;
if (counter[5]!=0)
cout<<"SLASH: "<<counter[5]<<endl;
if (counter[6]!=0)
cout<<"QSTRING: "<<counter[6]<<endl;
if (counter[7]!=0)
cout<<"OTHER: "<<counter[7]<<endl;
return 0;
}
extern int lANGLE=1, ... eND=8
This is supposed to be extern declaration, but due to explicit initialization it's actually a definition. So you end up defining all these variables in several translation units, leading to violation of One Definition Rule.
When you fix this, you'll have the same problem with map <int, int> counter;
What you should do is to answer yourself the question, why do you have to declare all of these in a header file. map <int, int> counter; is used only in main.cpp, so move it there. And the int variables can be replaced with one enum, because it seems you are going to use them as return values for getToken().
So it will be something like
enum Token {
lANGLE=1, rANGLE=2,iD=3,...
};
Token getToken(istream *br, string& lexeme);

Array implementation of stack

I wrote this program and it supposed to test for the correct use of the three grouping symbols "(",")";"[","]"; and "{","}". It is using the array implementation of the stacks and supposed to evaluate if it is good string or a bad string. For example: (a+b), [(a-b)+c] would be good and )a+b( etc. would be bad string. When i run the program i get only one error. I thought i am missing a semi-colon or something, but after looking through the code several time,i can't find it. Maybe i got tunnel vision. Can you please see what the problem here is? This is the error: project1.cpp:41: error: expected initializer before 'while'.
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
const int DefaultListSize = 100;
typedef char Elem;
class Astack {
private:
int size;
int top;
Elem *listArray;
public:
Astack (int sz = DefaultListSize)
{size = sz; top= 0; listArray = new Elem[sz];}
~Astack() {delete [] listArray;}
void clear() {top=0;}
bool push(const Elem& item) {
if (top == size) return false;
else {listArray[top++] = item; return true;}}
bool pop(Elem& it) {
if (top==0) return false;
else {it = listArray[--top]; return true;}}
bool topValue(Elem& it) const {
if (top==0) return false;
else {it = listArray[top-1]; return true;}}
bool isEmpty() const {if (top==0) return true;
else return false;}
int length() const{return top;}
}; //end of class Astack
Astack s;
const string LEFTGROUP="([{";
const string RIGHTGROUP=")]}";
int main()
while (!EOF) {
while (!EOL) {
ch = getc();
if (ch == LEFTGROUP[0]) {
s.push(ch);
}
if (ch == LEFTGROUP[1] {
s.push(ch);
}
if (ch == LEFTGROUP[2] {
s.push(ch);
}
} //checking for openers
while (!EOL) {
ch = getc();
if (s.top() == LEFTGROUP[0]) {
if (ch == RIGHTGROUP[0]) {
s.pop();
}
}
if (s.top() == LEFTGROUP[1]) {
if (ch == RIGHTGROUP[1]) {
s.pop();
}
}
if (s.top() == LEFTGROUP[2]) {
if (ch == RIGHTGROUP[2]) {
s.pop();
}
}
if (!s.empty()) {
cout<<"Bad String."<<endl;
else {
cout<<"Good String."endl;
}
}
}
return 0;
You forgot a { at the beginning of int main(). You should also end with }
int main(){
//your while code
return 0;
}

c++ referencing class functions error: identifier is undefined

I am trying to call a function for my stack class. If I have all of the functions within the main file the project works, however, when called from the class it says the the Error: identifier "function name" is undefined. I think it is a simple syntax error, but i can't find it.
main.cpp
#include<iostream>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "stack.h"
#define MAX 10
#define EMPTY -1
struct stack
{
char data[MAX];
int top;
};
int mystack::isempty(struct stack *s)
{
return (s->top == EMPTY) ? 1 : 0;
}
void mystack::emptystack(struct stack* s)
{
s->top=EMPTY;
}
void mystack::push(struct stack* s,int item)
{
if(s->top == (MAX-1))
{
printf("\nSTACK FULL");
}
else
{
++s->top;
s->data[s->top]=item;
}
}
char mystack::pop(struct stack* s)
{
char ret=(char)EMPTY;
if(!isempty(s))
{
ret= s->data[s->top];
--s->top;
}
return ret;
}
void mystack::display(struct stack s)
{
while(s.top != EMPTY)
{
printf("\n%d",s.data[s.top]);
s.top--;
}
}
int isoperator(char e)
{
if(e == '+' || e == '-' || e == '*' || e == '/' || e == '%' || e == '^')
return 1;
else
return 0;
}
int priority(char e)
{
int pri = 0;
if(e =='%' || e == '^')
pri = 3;
else
{
if (e == '*' || e == '/' || e =='%')
pri = 2;
else
{
if(e == '+' || e == '-')
pri = 1;
}
}
return pri;
}
void infix2postfix(char* infix, char * postfix, int insertspace)
{
char *i,*p;
struct stack X;
char n1;
emptystack(&X); // any time a class like this is called it says Error: identifier "emptystack"
// is undefined
i = &infix[0];
p = &postfix[0];
while(*i)
{
while(*i == ' ' || *i == '\t')
{
i++;
}
if( isdigit(*i) || isalpha(*i) )
{
while( isdigit(*i) || isalpha(*i))
{
*p = *i;
p++;
i++;
}
if(insertspace)
{
*p = ' ';
p++;
}
}
if( *i == '(' )
{
push(&X,*i);
i++;
}
if( *i == ')')
{
n1 = pop(&X);
while( n1 != '(' )
{
*p = n1;
p++;
if(insertspace)
{
*p = ' ';
p++;
}
n1 = pop(&X);
}
i++;
}
if( isoperator(*i) )
{
if(mystack::isempty(&X))
push(&X,*i);
else
{
n1 = pop(&X);
while(priority(n1) >= priority(*i))
{
*p = n1;
p++;
if(insertspace)
{
*p = ' ';
p++;
}
n1 = pop(&X);
}
push(&X,n1);
push(&X,*i);
}
i++;
}
}
while(!isempty(&X))
{
n1 = pop(&X);
*p = n1;
p++;
if(insertspace)
{
*p = ' ';
p++;
}
}
*p = '\0';
}
int main()
{
char in[50],post[50];
strcpy(&post[0],"");
printf("Enter Infix Expression : ");
fflush(stdin);
gets(in);
infix2postfix(&in[0],&post[0],1);
printf("Postfix Expression is : %s\n",&post[0]);
return 0;
}
stack.h
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
using namespace std;
class mystack
{
public:
int isempty(struct stack *s);
void emptystack(struct stack* s);
void push(struct stack* s,int item);
char pop(struct stack* s);
void display(struct stack s);
};
I am using visual studio if that helps.
EDIT: added comment for clarity.
Thanks,
Ryan
At a cursory glance, this function:
void emptystack(struct stack* s)
{
s->top=EMPTY;
}
Is missing the scope operator (::), so you probably intended to write it as:
void mystack::emptystack(struct stack* s)
{
s->top=EMPTY;
}
I'm not sure if that's your problem though, since "I'm trying to call a function" is a bit vague. You might want to narrow down precisely where the error is occurring, then edit your question with additional information.
Edit: In looking at your implementation a bit more, I'm not sure why you created the mystack class at all. It looks like you just want to define a bunch of functions that operate on your stack struct, which doesn't require a class definition. If you want to do it this way for some unusual reason, then you'll have to instantiate a mystack object before you can call its member functions. Something of the nature:
mystack * myStackObj = new mystack();
myStackObj->emptystack(&X);
Though I'm not sure why you would want to do this. The other alternative is to roll your stack struct into the class instead, either by making the whole struct a member of the class or by simply adding data and top to the class. Then if you instantiated a mystack object it would have the data of the stack and could call methods on its own data. I'd also suggest looking at a tutorial/documentation/book related to C++ classes and their usage. Here's one, but there are undoubtedly plenty of others.