I have looked over this for hours it seems like. This program will compile, it just can't detect errors correctly. And for some reason it will work when I type in hey [) or hey {], etc. But it won't work for hey[) or hey{]. Obviously in all cases it should detect an error but for some reason the space after 'hey' makes a difference.
#include<iostream>
#include <stack>
using namespace std;
bool delimiterMatching(char *file){
stack<char> x;
int count = 0;
char ch, onTop, check;
while(ch != '\0'){
ch = file[count];
if (ch == '(' || ch == '[' || ch == '{')
x.push(ch);
else if (ch == ')' || ch == ']' || ch == '}') {
onTop == x.top();
x.pop();
if((ch==')' && onTop!='(') || (ch==']' && onTop!='[') || (ch=='}' &&
onTop!= '{'))
return false;
}
count++;
}
if (x.empty())
return true;
else
return false;
}
int main()
{
char *test = new char();
cout << "enter sentence: ";
cin >> test;
if (delimiterMatching(test))
cout << "success" << endl;
else
cout << "error" << endl;
return 1;
}
With cin >> test you don't get a whole sentence, but only a string until cin encounters whitespace. So if you type (hey ), thest would be (hey and the closing brace would only be read by the next >>, whereas (hey) would work as expected.
You have a second issue with your test allocation, which might be too short for reasonable input.
Change main() as follows:
char *test = new char[256]; // enough space. COnsider also string
cout << "enter sentence: ";
cin.getline(test, 256); // full line input.
...
You have also two nasty bugs in delimiterMatching().
First you use an uninitialized ch in your while condition. Either initialise ch to a non nul char, or use while (file[count]).
And did you notice onTop == x.top(); ? Shouldn't it be onTop = x.top();?
Related
I am tasked to write a simple program that reads in a file, and determines if the characters '(' '[' and '{' and "balanced". Meaning, There is a matching closing bracket/brace/parentheses for each opening one.
I am having trouble with the input. We are to use input redirection, not an iostream object, taking advantage of the command line. We utilize a makefile and when I run the executable it tells me 2 errors: not using argc and argv[].
struct Contents {
int numP;
int numS;
int numC;
};
int main(int argc, const char* argv[]) {
char word;
Contents c;
while(cin >> word) {
if(word == '{' || word == '}') {
c.numC++;
}
if(word == '(' || word == ')') {
c.numP++;
}
if(word == '[' || word == ']') {
c.numS++;
}
}
if(c.numC % 2 == 0 || c.numP % 2 == 0 || c.numS % 2 == 0) {
cout << "Balanced" << endl;
}
else {
cout << "Not Balanced" << endl;
}
return 0;
}
What am I missing here to make the file redirection input work? When I run this in XCode I just enter a bunch of values and it never ends. I can't seem to do the input right.
Thank you!
You need to break out of the while loop, if you are reading from a file then your code should work as it is. I have just made a small change to the logic when checking whether it is balanced or not.
int main() {
char word;
Contents c;
while (cin >> word) {
if (word == '{' || word == '}') {
c.numC++;
}
if (word == '(' || word == ')') {
c.numP++;
}
if (word == '[' || word == ']') {
c.numS++;
}
}
// Edited here: Check using and instead of or.
if (c.numC % 2 == 0 && c.numP % 2 == 0 && c.numS % 2 == 0) {
cout << "Balanced" << endl;
} else {
cout << "Not Balanced" << endl;
}
return 0;
}
Update:
I have tested the code, so here is the output.
Here is the output. You can redirect the input to any file and it will scan the file until it reaches EOF.
Instructions:
using a value returning function
Write a program that prompts the user to input a sequence of characters and outputs the number of vowels.
This is the problem given by the instructor..
#include <iostream>
using namespace std;
bool isVowel(char ch);
int main() {
char ch;
cout << "Enter a character: ";
cin >> ch;
cout << ch << " is a vowel: " << isVowel(ch) << endl;
return 0;
}
bool isVowel(char ch){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
return true;
} else
return false;
}
char is a single character, not a sentence. For a sentence use a string.
string s;
cout << "Enter a sentence: ";
cin >> s;
Then use a loop to loop through each character of the sentence
for (char ch : s)
{
...
}
Then use isVowel to test a single character, and increment the count if found. The clue is in the name isVowel, not countVowels, so isVowel should test a single vowel and return true or false, not count the number of vowels.
int vowels = 0;
for (char ch : s)
{
if (isVowel(ch))
vowels++;
}
finally write isVowel to test a single character.
bool isVowel(char ch)
{
return ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u';
}
There are several problems here.
Firstly, you don't initialize vowels. You presumably mean int vowels = 0; or int vowels {0};.
Secondly, you are reading a single character with cin >> ch;. I suspect you mean to loop over an input string.
Thirdly, your signature for isVowel is bool isVowel(int vowels, char ch);, which returns a bool. But you have written your function as thought it is manipulating an integer total of vowels. This inconsistency doesn't make sense.
Fourthly, you assign the result of isVowel to a character in ch = isVowel(vowels,ch);. Then you call isVowel again with this updated ch in cout << isVowel(vowels, ch) << .... I'm not sure what you're attempting to do here, but this also doesn't make any sense.
You need to revisit all of this code. You probably want isVowel to actually return a boolean. You probably want to iterate over an entire input string, and adjust the value of vowels appropriately (after initializing it).
Your program is running an undefined behavior; you are using vowels without being initialized.
You can make function that takes the counter of vowels as a reference to an integer for example.
void isVowel(int& counter, char ch) {
std::string vowels{ "AaEeIiOoUu" };
for (auto c : vowels)
if(ch == c)
counter++;
}
int main(){
char ch;
int counter{};
while (std::cin >> ch)
isVowel(counter, ch);
std::cout << counter << endl << " vowels in this sentence." << endl;
}
#include <iostream>
using namespace std;
bool isVowel(int vowels, char ch);
So isVowel returns a bool. That would make sense if its purpose was to tell us whether a single character was a vowel or not. For some reason, we pass an integer called vowels to it. That doesn't seem to make any sense. What would it do with an integer value?
int main() {
char ch;
So ch is a single character. Okay.
int vowels;
And vowels is an integer with no particular value.
cout << "Enter a sentence: ";
cin >> ch;
Uh oh. We ask the user to enter a sentence but then we read in a single character. Remember, ch was a char.
ch = isVowel(vowels,ch);
Uh oh. We didn't assign vowels any particular value, so we've passed no particular value to isVowel. Also, we took the boolean value returned and assigned to a variable of type char. Why would we do that?
cout << isVowel(vowels, ch) << " vowels in this sentence." << endl;
Then for some reason we call isVowel again. That doesn't make much sense. Also, isVowel returned a bool (a yes or no). Why are we outputting that as if it was the number of vowels?
return 0;
}
// build a string counter and make it callable
bool isVowel(int vowels, char ch){
Okay, so isVowel returns a boolean and takes as input an integer and a character.
for (int i = 0; i < ch; i++){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
vowels++;
}
We are looping from zero to the value of the single character? That doesn't make sense.
}
return vowels;
}
Lots of problems here. Because there are so many fundamental problems with this code, it seems you've attempted a problem that's way beyond your C++ knowledge and you should attempt something much simpler first, such as accepting a sentence as input and repeating it back to the user without using any additional functions.
#include<iostream.h>
#include<conio.h>
void main()
{
char ch;
cout<<"Enter a character:";
cin>>ch;
if(ch==32)
cout<<"space";
else if(ch>=65 && ch<=90)
cout<<"upper case letter";
else if(ch>=97 && ch<=122)
cout<<"lower case letter";
else
cout<<"special character entered";
getch();
}
I need to check whether character entered is lower or upper case letter,special character, digit or space character. 32 is code for space but as I am entering space as ' ' on the console, its not recognizing ' ' as space.
Spaces are ignored by default, use noskipws
#include<iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character:";
cin>>noskipws>>ch;
if(ch==32)
cout<<"space";
else if(ch>=65 && ch<=90)
cout<<"upper case letter";
else if(ch>=97 && ch<=122)
cout<<"lower case letter";
else
cout<<"special character entered";
getchar();
return 0;
}
Also, if you're adding '' to the space then keep in mind that only the first character is being recognized.
The problem
cin >> ch discards whitespaces (including space, \t, \n, etc.) The correct way is to use get(ch):
cin.get(ch);
(noskipws is another option mentioned in #Samuel's answer, but get may be easier here for a single character.)
Other problems
Use <iostream> instead of <iostream.h>. <iostream.h> is not standard C++.
Use <cstdio>* instead of <conio.h>. <conio.h> is not standard C++.
Use int main() instead of void main(). void main() is not standard C++.
Use indentation instead of left-justifying. Left-justifying is less readable.
Use ch == ' ' instead of ch == 32. ch == 32 is not portable.
Use isupper(ch) instead of ch >= 65 && ch <= 90. ch >= 65 && ch <= 90 is not portable.
Use islower(ch) instead of ch >= 97 && ch <= 122. ch >= 97 && ch <= 122 is not portable.
Fixed code:
#include <iostream>
#include <cctype>
int main()
{
char ch;
std::cout << "Enter a character:";
std::cin.get(ch);
if (ch == ' ')
std::cout << "space";
else if (std::isupper(ch))
std::cout << "upper case letter";
else if (std::islower(ch))
std::cout << "lower case letter";
else
std::cout << "special character entered";
// std::cin >> ch; // only if you really demand it
}
* Even <cstdio> shouldn't be used in this case. If you do want to hold the window open, use getchar() or std::cin >> ch instead of getch(). The better way is to invoke it in a console.
Use characters themselves instead of their codes.
#include<iostream.h>
#include<conio.h>
void main()
{
char ch;
cout << "Enter a character:";
cin >> ch;
if (ch == ' ')
cout << "space";
else if (ch >= 'A' && ch <= 'Z')
cout << "upper case letter";
else if(ch >= 'a' && ch <= 'z')
cout << "lower case letter";
else
cout << "special character entered";
getch();
}
I'm writing a program that takes user input and uses stacks to convert an infix expression into a postfix expression based on precedence, with operands always going before operators. For example, if a user inputs:
(a+b*c)
then the program should display:
abc*+
so far, I have this:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
stack<char> s;
char input;
while (cin.get(input) && input != '\n')
{
if (isalnum(input))
cout << input << "\n";
else if (input == '(')
s.push(input);
else if (input == ')')
{
while (!s.empty() && s.top() != '(')
{
cout << s.top();
s.pop();
}
if(!s.empty())
s.pop();
else
cout << "ERROR: No Matching ( \n";
}
else if (s.empty() && input == '*'||'/'||'+'||'-' && s.top() < input) // Error Begins Here?
{
char a = '*';
char b = '/';
char c = '+';
char d = '-';
bool prec (char a, char b, char c, char d);
return ('*' > '/' > '+' > '-');
s.push(input);
}
else if (input == '*'||'/'||'+'||'-' && s.top() >= input)
while (!s.empty())
{
cout << s.top();
s.pop();
s.push(input);
}
}
while (!s.empty())
{
cout << s.top();
s.pop();
}
}
Which compiles and runs but is not functioning as it should. When an expression like "ab" is input, the program will display "ab" as it should but if I input "a+b+c", then only "a" will be displayed. This means the program is not placing the operators into the stack to be displayed later on. What I need help with is modifying the program so that when an operator is input, it should be added onto the stack and then displayed based on it's precedence (*>/>+>-) after the operands, when the input is done.
I'm quite new to C++ and programming in general, so any suggestions would be great.
else if (input == '*'||'/'||'+'||'-' && s.top() >= input)
This does not do what you think it does. You need to do
else if (input == '*'|| input == '/'|| input == '+'|| input == '-' && s.top() >= input)
And this looks like an error too
bool prec (char a, char b, char c, char d);
That's the syntax for a function prototype. Are you sure this compiles?
The problem is here:
bool prec (char a, char b, char c, char d);
return ('*' > '/' > '+' > '-');
I'm guessing this is intended to define a precedence function, but that's not what it's doing. The first line declares that such a function exists (and its arguments have nothing to do with the variables declared in the previous lines), and the second causes the whole program to terminate. If you want a function like this, you must define it outside main.
A slightly less dramatic bug is here:
if (s.empty() && input == '*'||'/'||'+'||'-' && s.top() < input)
First, this part
input == '*'||'/'||'+'||'-'
is interpreted as
(input == '*') || ('/') || ('+') || ('-')
The last three terms are true, the first is irrelevant. And I'm not even sure what s.top() does if s is empty.
This should be enough to go on. I suggest you start by building and testing routines that can, e.g., identify the operators and evaluate their precedence, before you try putting everything together in one program.
Falmarri is right just wanted to post that my self , and it compiles I tried it , but there is another thing : you said
else if (s.empty() && input == '*'||'/'||'+'||'-' && s.top() < input) // Error Begins Here?
Are you sure that even reached that point because when I runn it , it just stops on the :
while (cin.get(input) && input != '\n')
until I hit enter and even more you can enter more then one char from consol while in cin.get(input) but the input will contain only the first char you entered . To solve this I just put an
#include <conio.h>at the beginning an used
while ((input = getch()) && input != (char)13) in staid of you're code
short explanation
getch()
returns after you press only one character and
input != (char)13
is required in staid of
input != '\n'
because getch() return (char)13 for ENTER see ASCII table for more info.
I have a simple program that lists input in order of precedence, checking only for operators and ranking them like so, "*/+-":
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int prec(char op)
{
if (op == '*' || op == '/') return 0;
return 1;
}
bool compareprec(char a, char b)
{
return prec(a) < prec(b);
}
int main()
{
char input[] = "+-/*";
cin >> input;
sort(input, input + 4, &compareprec);
cout << input;
}
I'm trying to implement it within a more complex program that uses stacks to check alpha numerical input and do an infix to postfix conversion, ranking something that looks like this: "9*9+9" into "9 9 9 * +". The more complex program is as follows:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int prec(char op)
{
if (op == '*' || op == '/' || op == '+' || op == '-') return 0;
return 1;
}
bool compareprec(char a, char b)
{
return prec(a) < prec(b);
}
int main()
{
stack<char> s;
char input;
while (cin.get(input) && input != '\n')
{
if (isalnum(input))
cout << input << " ";
else if (input == '(')
s.push(input);
else if (input == ')')
{
while (!s.empty() && s.top() != '(')
{
cout << s.top() << " ";
s.pop();
}
if(!s.empty())
s.pop();
else
cout << "ERROR: No Matching ( \n";
}
else if (s.empty() && input == '*'|| input == '/'|| input == '+'|| input == '-')
{
sort(input, input + 4, &compareprec); // Error Begins Here?
s.push(input);
}
else if (input == '*'||input == '/'||input == '+'|| input =='-')
while (!s.empty())
{
sort(input, input + 4, &compareprec); // More Errors Here?
cout << s.top() << "\n ";
s.pop();
s.push(input);
}
}
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}
}
But I keep getting an error that says:
error: no matching function for call to 'sort(char&, int, bool (*)(char, char))'
error: no matching function for call to 'sort(char&, int, bool (*)(char, char))'
And I'm not sure why. I know it's probably something painfully obvious/silly but I can't figure it out. Any help would be appreciated. Thanks in advance!
sort expects something that can be iterated over.
Your working example has
char input[]
(an array of char)
Your non working example removes the array syntax and makes it a plain char
char input
When you attempt to do:
sort(input, input + 4, &compareprec)
In the working case, because you are providing an array, you're telling it to iterate from the beginning of input to 4 past the location. In the non-working case you're telling it to go from say 'a' to 'd' (which is 'a' + 4).
Why do you have to sort anything in the second example? You have maximally two operators you have to compare, one on the top of the stack and one in the input. Just use your compareprec-function and act accordingly based on the result.
And by the way, to make your code a little prettier, create a function:
bool is_operator(char s);
Almost forgot to tell you, the version of int prec(char a) in the second example is wrong, use the first one.