Writing a postfix calculator with a stack and iterator - c++

#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
string blah("512+4*+3−");
stack<int> astack;
int a=0;
int b=0;
int result=0;
int final=0;
for (string::iterator count=blah.begin(); count != blah.end(); count=count+1)
{
if (isdigit(*count))
{
astack.push(*count);
cout<<" "<<*count<<" ";
}
else
{
a=astack.top();
astack.pop();
b=astack.top();
astack.pop();
if(*count=='+')
{
result = a+ b;
}
else if (*count=='-')
{
result=a-b;
}
else if(*count=='*')
{
result=a*b;
}
astack.push(result);
}
}
final=astack.top();
cout<<final;
}
My problem is whenever I run it, the code seems to segment fault. When I tried running it with the operator commented it the stack seems to pop two values and I'm not really sure why

As PaulMcKenzie pointed out, your minus sign in the blah string is some sort of weird unicode character that looks like a normal minus sign, but it isn't. Since it's some weird unicode character, it is actually being stored in more than one byte in the string's memory, meaning your iterator for-loop is iterating more times than you would expect!
Put a cout << blah.length() << endl; right after you declare blah, and you'll see that the length is more than the expected 9 characters.
Also, this program will not output the right answer even when the problem above is fixed. You need to convert your ascii number characters (which are in the integer range [48,57]) to the equivalent integer values before you do any calculations with them.

If the code you posted is the actual code, then there is an issue with the string you posted.
string blah("512+4*+3−");
That last character after the 3 is not an ASCII minus sign. It is a Unicode character 0x2212. Change this to an ASCII minus and rerun the program.
What may have happened is that you started out with an ASCII minus, copied the text to another app, and the app tries to "fancy up" the minus by replacing it with more aesthetic looking character. Then you may have copied the text from this app back to your source code editor.

Related

make user enter a string of integers and output a different string

hi i am having trouble starting this program as i am new and have no idea how to use loops to construct this thanks
here are the directions:
For this assignment, write a program named assignment2 (source is the same name with .cpp extension) to
prompt the user for an integer value (ignore negative values) and then output this value using the following rules:
Each digit within the integer value is to be displayed the same number of times as the value of the digit
itself, with one exception...the digit 0 will be displayed once, like the digit 1.
Separate each string of digits using a single dash character.
For example:
If the input value is 120473, the display should look like:
1-22-0-4444-7777777-333
If the input value is 5938061, the display should look like:
55555-999999999-333-88888888-0-666666-1
In addition, ask the user if they would like to retry using another integer value. If so, repeat the above. End the
program when the user chooses to quit (does not want to retry).
This assignment is an exercise in using the following:
Unary Operators:
! ++ --
Binary Operators:
+ - * / % && ||
Data types:
bool
char
int
enum
Flow control:
if-else
switch
do-while loop
while loop
for loop
In addition, you are allowed to use any necessary functions provided by the Math library. To include the Math
library, add the following line to your list of include statements:
#include <cmath>
For most digit manipulation assignments, I recommend treating the number as a string of characters rather than as a number.
The Foundation
Let's start with the foundation:
#include <iostream>
#include <string>
#include <cstdlib>
using std::cout;
using std::cin;
using std::getline;
int main(void)
{
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
return EXIT_SUCCESS;
}
The above program will hopefully keep the console (terminal) window open until the Enter key is pressed.
Getting The Input
We'll ask the User for a number, this is also known as prompting:
// The prompt text doesn't change so it's declared as const.
// It's declared as static because there is only one instance.
static const char prompt[] = "Enter a number: ";
cout.write(prompt, sizeof(prompt) - 1U); // Subtract 1 so the terminating nul is not output.
// Input the number as text
string number_as_text;
getline(cin, number_as_text);
Printing The Digits
Really, before this step, you should verify that the text only contains numbers. Repeat the prompting until the User inputs nothing or valid data.
A string can be accessed as an array. So we'll set up a loop:
const unsigned int length = number_as_text.length();
for (unsigned int index = 0U;
index < length;
++index)
{
// Extract the digit.
const char c = number_as_text[index];
// Verify it is a digit.
if (!isdigit(c))
{
continue;
}
unsigned int quantity = c - '0'; // Convert to a number.
if (quantity == 0) quantity = 1; // The requirements lie, for zero there is a quantity of 1.
// Use "quantity" to print copies of the character.
}
cout << "\n";
Stuff
I'm not going to write the entire program for you, as you haven't paid for my services. So you will have to figure out when to print the '-' and how to print many copies of the digit.
If this answer is not correct, please update your question with some clarifications or restrictions.

Why it works when I type multiple characters in a character variable?

I am a new C++ user.
My code is as following:
#include <iostream>
using namespace std;
int main()
{
int option = 1;
char abstract='a';
while(option == 1){
char temp;
cin>> temp;
abstract = temp;
cout << abstract;
option = 1;
if(abstract == '!'){
option = 0;
}
}
return 0;
}
And when I typed something like: abcdefg
all the characters are on the screen,why? It's just because of the compiler?
In fact, only one character at a time is stored in your char. cin>>temp; reads a single char at a time since more characters would not fit there. The loop simply reads and prints one character after the other.
As a visualization hint, try echoing your characters with cout<<abstract<<endl;. You will see a single character per line/iteration.
Your terminal does not restrict the number of characters typed in , that's why you can type as many as you want. Your c++ compiler would read only one of the characters because 'temp' is of type char. you can type an 'if' statement to check the number of characters typed in the terminal
Because of the while loop, which processes each character in turn. Not sure what you expected to happen.
Print it out with delimiters to see that there's never more than a single character printed per iteration:
cout << "'" << abstract << "'";
The terminal window itself is responsible for reading the characters and echoing them back to the screen. Your C++ program asks the terminal for characters and, in this sort of program at least, has no effect on how those characters are displayed.

What is wrong with my UVa code

I tried to solve this problem in UVa but I am getting a wrong answer and I cant seem to find the error
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2525
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,j,k,i=1;
char a[1000];
while(scanf("%d",&t)!=EOF && t)
{
int sum=0;
getchar();
gets(a);
k=strlen(a);
for(j=0;j<k;j++)
{ if(a[j]=='a'||a[j]=='d'||a[j]=='g'||a[j]=='j'||a[j]=='m'||a[j]=='p'||a[j]=='t'||a[j]=='w'||a[j]==32)
sum=sum+1;
else if(a[j]=='b'||a[j]=='e'||a[j]=='h'||a[j]=='k'||a[j]=='n'||a[j]=='q'||a[j]=='u'||a[j]=='x')
sum=sum+2;
else if(a[j]=='c'||a[j]=='f'||a[j]=='i'||a[j]=='l'||a[j]=='o'||a[j]=='r'||a[j]=='v'||a[j]=='y')
sum=sum+3;
else if(a[j]=='s'||a[j]=='z')
sum=sum+4;
}
printf("Case #%d: %d\n",i,sum);
i++;
}
return 0;
}
In the problem description there is a single number that indicates the number of texts that will be in the input afterwards. Your original code was trying to read the number before every row of input.
The attempt to read the number in each one of the rows will fail since the input character set does not include any digits, so you could be inclined to think that there should be no difference. But there is, when you try to read a number it will start by consuming the leading whitespace. If the input is:
< space >< space >a
The output should be 3 (two '0' and one '2' keys), but the attempt to read the number out of the line will consume the two leading whitespace characters and the later gets will read the string "a", rather than " a". Your count will be off by the amount of leading whitespace.
separate your code into functions that do specific things: read the data from the file, calculate the number of key presses for each input, output the result
Benefit:
You can test each function independently. It is also easier to reason about the code.
The maximum size of an input is 100, this means you only need an array of 101 characters( including the final \0) for each input, not 1000.
Since this question is also tagged C++ try to use std::vector and std::string in your code.
The inner for seems right at a cursory glance. The befit of having a specialized function that computes the number of key presses is that you can easily verify it does the correct thing. Make sure you check it thoroughly.

ASCII and isalpha if statement issue

I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC

Why does this program display seemingly random characters? (C++)

Well, not random, because its the same every time, but
#include<iostream>
using namespace std;
int main()
{
char box[10][10];
for(int i=-1;i<11;i++)
{
cout<<"---------------------"<<endl<<"|";
for(int j=0;j<10;j++)
{
cout<<box[j][i]<<"|";
}
cout<<endl;
}
intx;cin>>x;
return 0;
}
outputs a series of international characters (well, not all of them are 'international' per se, but I get things like pi and spanish inverted question mark). Anyways, I know this is becuase the program access chars that have not been initialized, but why do particular values create particular symbols, what are the ASCII values of the symbols (if they have ASCII values) and how can I get the symbols without glitching my program?
Your loop over i doesn't make sense...
for(int i=-1;i<11;i++)
This will hit two indices that aren't valid, -1 and 10, when you reference box here:
cout<<box[j][i]<<"|";
It should be 0 to < 10 like the other loop.
Also you haven't initialized the contents of box to anything, so you're printing uninitialized memory. You have to put something into your "box" before you can take anything out.
The symbols themselves are probably extended ASCII, you can get at them through any extended ASCII table. This one came up first on google. For instance, you could do:
cout << "My extended ascii character is: " << (char)162 << endl;
to get a crazy international o.
For the same reason that
#include <iostream>
using namespace std;
int main()
{
int x;
cout << x;
}
displays a random value. Uninitialised variables (or arrays) contain garbage.
for(int i=-1;i<11;i++)
That line is suspect. -1 to 10? Should be 0 to 9.
The ASCII-code is
(int)(box[j][i])
You just print ordinary chars which are ASCII-characters with codes from 0 to 255.
When printing wchar_ts the same memory is interpreted as other characters.
Your loop should be in [0; 10[ not in [-1; 11[
The symbols displayed by the program depend on:
the contents that happens to be in the uninitialised variables, and
the locale of your computer or the encoding used in presentation.
A Unicode reference would probably be the best source for identifying the codes required to display particular symbols.
Consider that your users may not have the same encoding (or fonts with the correct symbols) selected by default. You should either check the current locale, or force one specific to your output to ensure your output renders the way you wish.