c++ Delimiter Matching - c++

This program basically just checks that a statement (mathematical) is properly constructed considering the brackets, parenthesis, and curly-braces. It uses a stack to compare the most recently read delimiter to see if the ending type of that delimiter exists, otherwise it says it is not constructed properly. I'm stuck, as it always returns that the statement is incorrect. This is what I have so far:
#include <iostream>
#include <stack>
using namespace std;
bool delimiterMatching(char* file);
void main(){
char fileName[50];
cout << "Enter a statement (Ex. s=t[5]+u/(v*(w+y)); : ";
cin >> fileName;
cout << endl;
if(delimiterMatching(fileName))
cout << endl << "Your statement was constructed successfully." << endl;
else cout << endl << "Your statement is incorrectly constructed." << endl;
}
bool delimiterMatching(char* file){
stack<char> var;
int counter = 0;
char ch, temp, popd;
do{
ch = file[counter];
if(ch == '(' || ch == '[' || ch == '{')
var.push(ch);
else if(ch == '/'){
temp = file[counter+1];
if(temp == '*')
var.push(ch);
else{
ch = temp;
continue;
}
}
else if(ch == ')' || ch == ']' || ch == '}'){
popd = var.top();
var.pop();
if(ch != popd)
return false;
}
else if(ch == '*'){
temp = file[counter+1];
popd = var.top();
var.pop();
if(temp == '/' && popd != '/')
return false;
else{
ch = temp;
var.push(popd);
continue;
}
}
counter++;
}while(ch != '\n');
if(var.empty())
return true;
else return false;
}
I've already tried googling for some hints, but got nothing too helpful. I debugged it, and if I use "s=t[5]+u/(v*(w+y));", when it reads the second bracket after the 5, it obviously isn't the same char. So how do I compare the opening symbol with the ending symbol?
I appreciate any help. I'll edit this/comment it if I figure it out myself. Thanks for your time!
I got it working this is the final code:
#include <iostream>
#include <stack>
using namespace std;
bool delimiterMatching(char* file);
void main(){
char fileName[50];
cout << "Enter a statement (Ex. s=t[5]+u/(v*(w+y)); : ";
cin >> fileName;
cout << endl;
if(delimiterMatching(fileName))
cout << endl << "Your statement was constructed successfully." << endl;
else cout << endl << "Your statement is incorrectly constructed." << endl;
}
bool delimiterMatching(char* file){
stack<char> var;
int counter = 0;
char ch, temp, popd;
do{
ch = file[counter];
if(ch == ';')
break;
if(ch == '(' || ch == '[' || ch == '{')
var.push(ch);
else if(ch == '/'){
temp = file[counter+1];
if(temp == '*')
var.push(ch);
else{
counter++;
continue;
}
}
else if(ch == ')' || ch == ']' || ch == '}'){
popd = var.top();
var.pop();
if((ch==')' && popd!='(') || (ch==']' && popd!='[') || (ch=='}' && popd!='{'))
return false;
}
else if(ch == '*'){
temp = file[counter+1];
popd = var.top();
var.pop();
if(temp == '/' && popd != '/')
return false;
else{
counter++;
var.push(popd);
continue;
}
}
counter++;
}while(ch != '\n');
if(var.empty())
return true;
else return false;
}

Your checking if the closing bracket (eg. ')', ']' or '}') matches the value popped off the stack. They are never going to be equal because you are only pushing the left sides of the brackets ('(', '[' or '{'), while comparing it with the right side of the brackets.
It should look something like this:
else if(ch == ')' || ch == ']' || ch == '}'){
popd = var.top();
var.pop();
if((ch==')' && popd!='(') || (ch==']' && popd!='[') || (ch=='}' && popd!='{'))
return false;
}

Related

How to fix not printing any character and just count vowels and characters and read every character in a file

I just want to read every character in a file where I put characters from A TO Z but the program prints A every time and count vowels 4 and character 25 but expectation was to printing vowels 5 and characters 26 how to fix this program fixing from last 4 hours but nothing progress?
Code:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
int i, count = 0, vowel_count = 0;
string file_name;
cout << "enter file name:";
cin >> file_name;
ifstream fin;
fin.open(file_name);
char ch;
while (!fin.eof()) {
fin.get(ch);
cout << ch;
while (fin >> ch) {
i = ch;
if ((i > 63 && i < 91) || (i > 96 && i < 123))
count++;
if (i == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch == 'o' || ch == 'O' || ch == 'u' || ch == 'U')
vowel_count++;
}
cout << "\n No. of Characters in a File : " << count;
cout << "\n No. of vowel characters in the File : " << vowel_count;
}
fin.close();
return 0;
}
You have some really minor erros in the code, which I fixed for you.
Additionally, I added a check, if the file could be opened or not. That is the problem in most cases.
Please see below:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
int count = 0, vowel_count = 0;
string file_name;
cout << "\nEnter file name: ";
cin >> file_name;
ifstream fin(file_name);
if (fin) {
char ch;
while (fin.get(ch)) {
cout << ch;
if ((ch >= 'A' && ch <= 'Z') || (ch > 'a' && ch <= 'z'))
count++;
if (ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch == 'o' || ch == 'O' || ch == 'u' || ch == 'U')
vowel_count++;
}
fin.close();
cout << "\n No. of Characters in a File : " << count;
cout << "\n No. of vowel characters in the File : " << vowel_count;
}
else std::cerr << "\n\n*** Error. Could notopen '" << file_name << "'\n\n";
return 0;
}

How can I make backspace not count as a character?

So, I have to encrypt my console application with a password, i did something that's working but there is a problem, backsapce doesn't erase the character entered, it is also counted as a character, how can I make it to do its job, to erase the character?
This is the code:
void main()
{
char password[20], my_password[20] = "password";
int i;
char ch;
system("cls");
cout << "PASSWORD: ";
i = 0;
do
{
ch = _getch();
password[i] = ch;
if (ch != 27 && ch != 13 && ch != 9)
cout<<"*";
else
break;
i++;
} while (i < 19);
password[i] = '\0';
if (strcmp(password, my_password) != 0)
{
cout << "\n\nIncorrect password !!!";
cin.get();
return;
}
cout << "\n\nPassword is correct !";
cout <<"\n\nThe program is executed !";
cin.get();
}
void main()
{
char password[20], my_password[20] = "password";
int i;
char ch;
system("cls");
cout << "PASSWORD: ";
i = 0;
do
{
ch = _getch();
if (ch == 8)
{
i--;
cout << "\b \b";
continue;
}
password[i] = ch;
if (ch != 27 && ch != 13 && ch != 9)
cout << "*";
else
break;
i++;
} while (i < 19);
password[i] = '\0';
if (strcmp(password, my_password) != 0)
{
cout << "\n\nIncorrect password !!!";
cin.get();
return;
}
cout << "\n\nPassword is correct !";
cout << "\n\nThe program is executed !";
cin.get();
}
Not the cleanest code but it works. Decrement the counter to over write the previous character and output two backspace characters separated by a space.
"how can I make it to do its job, to erase the character?"
Use a curses library. Like ncurses.
You could check if the character received is a backspace, if it is decrement i which will effectively remove the last character.
i = 0;
do
{
ch = _getch(); // get the character
if(ch == DEL || ch == BS) // check for backspace
{
i--;
cout << BS;
}
else if(ch >= ' ' && ch <= '~') // check if its valid ASCII
{
password[i] = ch;
cout << "*";
i++;
}
else if (ch == 27 || ch == 13 || ch == 9) // check if entry is complete
{
break;
}
} while (i < 19);
password[i] = '\0';
somewhere else
#define BS '\b'
#define DEL 127

I want to check if brackets are in correct place or not but my code is not executing correctly

here is my code it is working fine now but not giving the desire output
ex for eq {a+(b-c)*d} the output should be
"bracket matched popping )
bracket matched popping }"
but output is
"bracket dose not matched"
#include <bits/stdc++.h>
using namespace std;
main() {
string exp;
cin >> exp;
// cin.getline(exp);
stack <char> s;
for(int i = 0; exp[i] != '\0'; i++) {
if(exp[i] == '{' || exp[i] == '(' || exp[i] == '[') {
s.push(exp[i]);
continue;
} else if(exp[i] == '}' || exp[i] == ')' || exp[i] == ']') {
if(s.top() == exp[i]) {
cout << "bracket matched popping " << s.top() << endl;
s.pop();
continue;
} else {
cout << "bracket dose not matched" << endl;
break;
}
} else {
continue;
}
}
}
because ( is not ) not [ is not ] nor { is not }
when you read a ( you have to push a ) rather than a ( etc, or you have to change the test (s.top() == exp[i])
This line is wrong, C++ strings are not null terminated
for(int i = 0; exp[i] != '\0'; i++) {
Do this
for(size_t i = 0; i < exp.size(); i++) {
Your comparison for the parenthesis match is wrong:
if(s.top() == exp[i]) {
That would mean that you expect '(' to close '('.
You need to expand that comparison to the respective expected opening parenthesis - i.e., if you currently encounter ']', you need to check for '[' on the stack; don't check for equality, but check explicitly both s.top() and exp[i] values; just to give you an idea:
} else if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') {
if ((s.top() == '(' && exp[i] == ')') ||
//... check for '[' matching ']' and '(' matching ')'...

Fixing uninitialized local variable error

I am working on a project right now and when I try to run what I have below it gives me an error that says "uninitialized local variable 'userOption' used" on line 22, while (isValidOption(userOption) == true) {.
How do I fix that error? Thank you.
#include<iostream>
#include <string>
using namespace std;
char toupper(char ch) {
if (ch >= 'A'&&ch <= 'Z')
return(ch);
else
return(ch - 32);
}
bool isValidOption(char ch) {
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X')
return(true);
else
return(false);
}
char getMainOption() {
string UserInput;
char userOption;
while (isValidOption(userOption) == true) {
cout << "Choose One of the following options\n";
cout << "I--List Our Inventory\n";
cout << "O--Make an Order\n";
cout << "L--List all Orders made\n";
cout << "X--Exit\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
if (!isValidOption(userOption)) {
cout << "Invalid String\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
}
if (userOption == 'I')
cout << "Listing Our Inventory\n";
else if (userOption == 'O')
cout << "Make an order\n";
else if (userOption == 'L')
cout << "Listing all orders\n";
}
return userOption;
}
int main() {
char choice;
choice = getMainOption();
system("pause");
return 0;
}
What the error is saying that you're trying to read from userOption before you've ever written to it. If a variable is uninitialized, its memory contents will be full of junk left behind by other functions and it can easily cause bugs. In your case, you'll want to read input from the user into userOption before you do any logic on it. This can be done with a do-while loop:
char userOption; // not yet initialized
do {
...
cin >> userOption; // userOption gets initialized here on first loop run
} while (isValidOption(userOption)); // no need for == true, that's a tautology :-)
// NOTE: perhaps you want to loop while the input is INvalid, as in
// while (!isValidOption(userOption)); ?
A couply code-review comments I would additionally give are:
std::toupper already exists in <cctype>. Docs are here
return is not a function call and it's better to write return ch; than return(ch);
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X'){ return true; } else { return false; } is completely equivalent to the shorter return ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X';
Also take a look at system(“pause”); - Why is it wrong?
Happy coding! Let me know if questions remain

C++ Printing strange characters

So I have this program below and currently after I run it outputs this:
abcdefghijklmnopqrstuvwxyz
eklpyqrbgjdwtcaxzsnifvhmou
TEst
iyniЉhb�{���{���`�5b�v4b�q4b�{����8b�`�5b��`{���{����o���7�vb��{�����or��o���#`�lhb���5b��`x#
any reason why?
also the lines which are meant to be randomised currently aren't random
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <fstream>
#include <string>
using namespace std;
int main()
{
char Text[256];
array<char, 26> letters;
iota(letters.begin(), letters.end(), 'a');
for(char c: letters) //Array before shuffling
{
cout << c;
}
cout << '\n';
random_shuffle(letters.begin(), letters.end());
for(char c: letters) //After shuffling
{
cout << c;
}
cout << '\n';
cin.getline (Text,256);
for (char & c : Text)
{
if (c == 'a' || c == 'A')
{
cout << letters[0];
}
else if (c == 'b' || c == 'B')
{
cout << letters[1];
}
else if (c == 'c' || c == 'C')
{
cout << letters[2];
}
else if (c == 'd' || c == 'D')
{
cout << letters[3];
}
else if (c == 'e' || c == 'E')
{
cout << letters[4];
}
else if (c == 'f' || c == 'F')
{
cout << letters[5];
}
else if (c == 'g' || c == 'G')
{
cout << letters[6];
}
else if (c == 'h' || c == 'H')
{
cout << letters[7];
}
else if (c == 'i' || c == 'I')
{
cout << letters[8];
}
else if (c == 'j' || c == 'J')
{
cout << letters[9];
}
else if (c == 'k' || c == 'K')
{
cout << letters[10];
}
else if (c == 'l' || c == 'L')
{
cout << letters[11];
}
else if (c == 'm' || c == 'M')
{
cout << letters[12];
}
else if (c == 'n' || c == 'N')
{
cout << letters[13];
}
else if (c == 'o' || c == 'O')
{
cout << letters[14];
}
else if (c == 'p' || c == 'P')
{
cout << letters[15];
}
else if (c == 'q' || c == 'Q')
{
cout << letters[16];
}
else if (c == 'r' || c == 'R')
{
cout << letters[17];
}
else if (c == 's' || c == 'S')
{
cout << letters[18];
}
else if (c == 't' || c == 'T')
{
cout << letters[19];
}
else if (c == 'u' || c == 'U')
{
cout << letters[20];
}
else if (c == 'v' || c == 'V')
{
cout << letters[21];
}
else if (c == 'w' || c == 'W')
{
cout << letters[22];
}
else if (c == 'x' || c == 'X')
{
cout << letters[23];
}
else if (c == 'y' || c == 'Y')
{
cout << letters[24];
}
else if (c == 'z' || c == 'Z')
{
cout << letters[25];
}
else if (c == ' ')
{
cout << ' ';
}
else if (c == '/n')
{
return 0;
}
else
{
cout << c;
}
}
}
else if (c == '/n')
{
return 0;
}
Should be
else if (c == '\n')
{
return 0;
}
However, if you're looking for the end of your input, you actually want
else if (c == '\0')
{
return 0;
}
Which is a null terminator which indicates the end of a string. Basically you're getting all the junk that is stored in the entire 256 character array.
However, that doesn't help with your 29 if else statements. Try this:
if(c == ' '){ // Space
cout << ' ';
}
else if(c >= 'A' && c <= 'Z'){ // Uppercase
cout << letters[c - 'A'];
}
else if(c >= 'a' && c <= 'z'){ // Lowercase
cout << letters[c - 'a'];
}
else if(c == '\0'){ // End of string
return 0;
}
else{ // Anything else
cout << c;
}
How it works:
There are not "letters" in a computer, only binary. 'A' doesn't exist, but 01000001 which is 65 which is A does. So if you enter an 'A', your program will see a 65. However, I just happen to know that in your letters array, you have an A in position 0, so letters[0] == letters['A' - 'A']. The same logic can be used for B, C, D, ect. The same thing for the lowercase letters, they just at a different range (97-122).
Problem is here
else if (c == '/n') // '/n' is not correct
change it to
else if (c == '\0') // Check EOF