How to add characters from a file that are not evenly spaced? - c++

I'm taking C++ for the first time. And I'm a bit stuck on the final entry calculation.
5+6- 7 -8 + 9 + 10 - 11;
The question deliberately spaces things out of order and I don't know how to account for it. Any help on this would be amazing as I don't know what I'm missing. Thank you so much!
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int val;
while (cin >> val)
{
string op;
while (cin >> op)
{
if (op == ";")
{
cout << val << endl;
break;
}
int num;
if (! (cin >> num)) {
cout << "a number is expected after '" << op << '\'' << endl;
return -1;
}
if (op == "+")
{
val += num;
}
else if (op == "-")
{
val -= num;
}
else {
cout <<"invalid operator '" << op << '\'' << endl;
return -1;
}
}
}
return 0;
}

You can do like following. See it working here:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int val;
int num;
char op;
bool isNotStop(true);
cin>>val;
while (isNotStop)
{
cin.get(op);
//cout<<"Craracter is: ["<<op << "]"<<endl;
if(isspace(op)) continue;
switch(op)
{
case '+':
if (!(cin >> num))
{
cout << "a number is expected after '" << op << '\'' << endl;
return -1;
}
val += num;
break;
case '-':
if (!(cin >> num))
{
cout << "a number is expected after '" << op << '\'' << endl;
return -1;
}
val -= num;
break;
break;
case ';':
isNotStop = false;
break;
default:
{
cout <<"invalid operator '" << op << '\'' << endl;
return -1;
}
}
}
cout<<"Result: "<<val;
return 0;
}

I'm new here and this is my first attempt at answering a question. This might not be the best way to do it.
I think you should read the whole thing in a string with getline(cin, string), then go through the string with a for loop and get rid of all spaces. Then you can define a string stream from the resulting string and use it instead of cin.
It will look something like this:
string s1,s2;
getline(cin, s1);
for (int i = 0; i < s1.length(); i++) {
if (s1[i] != ' ')
s2 += s1[i];
}
stringstream ss;
ss << s2;
and from now on use ss instead of cin.
just make sure to include sstream and string headers.

Related

expected unqualified id before return 0

I'm new to C++. I have errors. But, i dont know how to fix it. Could anyone please help me? Thank you.
P - Print numbers
A - Add a number
M - Display mean of the numbers
S - Display the smallest number
L - Display the largest number
Q - Quit
Errors : expected unqualified id before return 0
error : expected ';' before {}
#include <iostream>
#include <vector>
using namespace std;
int main(){
char input {};
vector <double> numbers {};
int number{};
int sum{};
int min_number{};
int max_number{};
bool condition {true};
cout << "Enter a command" << endl;
cin >> input;
if(numbers.size() > 0){
while(condition){
if (input == 'P' || input == 'p'){
for(auto x: numbers)
cout << x << endl;
}
else if(input == 'A' || input == 'a'){
cout << "Enter a number";
cin >> number;
numbers.push_back(number);
}
else if(input == 'M' || input == 'm'){
for(auto x : numbers)
sum += x;
cout << sum / numbers.size() << endl;
}
else if(input =='S' || input == 's'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) < min_number)
min_number =numbers.at(i);
}
else if(input =='L' || input == 'l'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) > max_number)
max_number =numbers.at(i);
}
else if(input =='Q' || input == 'q'){
condition {false};
}
}
cout << "[] - list is empty, unable to calculate" << endl;
}
return 0;
}
In your section dealing with Q/q, the statement:
condition {false};
is not a valid form of assignment, you should instead use:
condition = false;
The braces are fine for initialisation, but that's not what you're trying to do on that line.
As an aside, this line:
if(numbers.size() > 0){
seems a little strange. Since you initialise the list to empty, the main loop will never start (because it's inside the if block) even though you have already asked the user for input.
That's a runtime error rather than a syntax error but you'll still need to fix it at some point.
I suspect that particular should should be done only as part of the calculation of the mean, so as to avoid dividing by zero.
I have written this for you. Since, you're a learner, I think that you should be practicing better things like STL functions and not using using namespace std; at top.
You may find some things new, but don't be frightened, just search them on some website like cppreference and see what that entity do and how to effectively use it.
There were many logical errors. #paxdiablo has mentioned them in his answer. I have removed every of them and this code works.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <vector>
int main() {
std::vector<double> numbers;
while (true) {
char input;
std::cout << "Enter a command: ";
std::cin >> input;
switch (std::toupper(input)) {
case 'P':
if (numbers.empty())
std::cerr << "The list is empty!" << std::endl;
else {
for (auto &&i : numbers)
std::cout << i << ' ';
std::cout << std::endl;
}
break;
case 'A': {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
numbers.push_back(number);
break;
}
case 'M':
if (numbers.empty())
std::cerr << "The list is empty! Cannot perform the operation!!";
else {
int sum = 0;
for (auto &&i : numbers)
sum += i;
std::cout << "Mean: " << (sum / numbers.size()) << std::endl;
}
break;
case 'S':
std::cout << "Smallest Number: " << *std::min_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'L':
std::cout << "Largest Number: " << *std::max_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'Q':
return 0;
default:
std::cerr << "Unrecognised Command!!" << std::endl;
}
}
return 0;
}

Recieving error "cannot dereference out of range deque iterator" when utilizing top()

I'm creating a simple program to evaluate post fix expressions but it won't run after successfully compiling due to "Expression: cannot dereference out of range deque iterator" whenever it reaches the assignment of the operand variables on lines 24 & 26. Why won't it run correctly when the program only reaches that point after filling the stack with number values?
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
int main()
{
stack<int> mystack;
string answer;
int result;
string done = "Y";
while (done == "Y" || done == "y") {
cout << "Please enter the RPN expression to be evaluated: ";
getline(cin,answer);
for(int i = 0; i < answer.length(); i++) {
if(answer[i] == ' ' || answer[i] == ':') {
continue;
}
if (isdigit(answer[i]) == false) {
cout << "Token = " << answer[i];
int operand2 = mystack.top();
mystack.pop();
int operand1 = mystack.top();
mystack.pop();
cout << " Pop " << operand2 << " Pop " << operand1;
if(answer[i] == '+') { //operation statements
result = operand1 + operand2;
}
else if(answer[i] == '-') {
result = operand1 - operand2;
}
else if(answer[i] == '*') {
result = operand1 * operand2;
}
else if(answer[i] == '/') {
result = operand1 / operand2;
}
mystack.push(result); //result returns to stack
cout << " Push " << result << endl;
}
else if(isdigit(answer[i]) == true){
int operand = 0;
while(i < answer.length() && isdigit(answer[i]) == true) {
operand = (operand*10) + (answer[i] - '0');
i++;
}
i--;
mystack.push(operand);
cout << "Token = " << operand << " Push " << operand << endl;
}
}
cout << "Token = Pop " << mystack.top() << endl << endl;
mystack.pop();
cout << "type 'Y' or 'y' to continue or type any other letter to quit: ";
getline(cin, done);
}
}
Here is a simple solution to the problem. This version uses ints and uses a stack of strings. This can easily be converted to doubles by replacing int with double throughout the file,
This uses getline() and istringstream to parse the input.
It also uses stringstream to convert numbers to strings and back.
You have to be careful when parsing multiple words from each line. This codes redirects the input line to ss, an istringstream object, and then takes tokens from that object.
Also, this will print the stack if you type "s".
Finally, you can arbitrarily load the stack with a series of space-separated numbers, or you can enter numbers one at a time. The stack is used when an operator is entered.
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
///////////////////////
/// top_and_pop()
/// Save the top value from a stack, and then pop the stack
/// If the stack is empty, return the string "0".
/// If the stack was not empty, return the popped element.
std::string top_and_pop(std::stack<std::string> &stack)
{
std::string return_string;
if (stack.empty()) {
return_string = "0";
std::cout << "Stack Empty, returning 0" << std::endl;
} else {
return_string = stack.top();
std::cout << "Popping " << return_string << std::endl;
stack.pop();
}
return return_string;
}
//////////////////////
/// is_number
/// Parse number into a int using std::stringstream.
/// If successful, then, the stringstream will be empty.
/// Return: true if the str would successfully parse as a int
bool is_number(const std::string &str)
{
std::istringstream ss(str);
int number;
ss >> number;
if (!ss.fail() && ss.eof())
return true;
ss >> std::ws; // not needed in this program, because we already parsed the
// input to a single word without whitespace. Needed for parsing a single line
// that may contain any set of chars.
return !ss.fail() && ss.eof();
}
/////////////////////
/// is_operator
/// return false if str is not a single character or if an operator is not found
/// acceptable operators are anyof "+-*/"
bool is_operator(const std::string &str)
{
return (str.length() == 1 &&
str.find_first_not_of("+-*/") == std::string::npos);
}
/////////////////////
/// string_to_int
/// convert string to int
/// Check to be sure string can convert to a int before calling
/// if conversion fails, return 0;
int string_to_int(const std::string &str)
{
std::stringstream stream;
int number = 0;
stream << str;
stream >> number;
return number;
}
//////////////////////
/// stack_to_string
///
/// print elements of stack
std::string stack_to_string(std::stack<std::string> stack)
{
std::string return_string;
while (!stack.empty()) {
return_string += stack.top() + " ";
stack.pop();
}
return return_string;
}
int main()
{
std::stack<std::string> mystack;
std::string input_line;
bool done = false; /// flag to indicate that calcualtor is closing
std::string token_str;
int operand1, operand2, result;
std::cout
<< "Please enter an RPN expression. Expression may consist of any \n"
"combination of space-separated numbers or operators.\n"
"Operators may include '+', '-', '*', '/'. The stack is initialized\n"
"with an unlimited supply of zeroes.\n\n"
"Type 's' to print the current stack.\n"
"To exit, type a 'y'" << std::endl;
do {
getline(std::cin, input_line);
std::stringstream ss(input_line);
/// loop through all tokens in this input line
while (ss >> token_str) {
// Only numbers are allowed on the stack.
// If the current token is a number, push it on the stack as a string
if (is_number(token_str)) {
mystack.push(token_str);
} else if (is_operator(token_str)) {
operand2 = (int) string_to_int(top_and_pop(mystack));
operand1 = (int) string_to_int(top_and_pop(mystack));
// switch does not accept string as a type, and we checked to ensure
// it is a single character operand that is handled in the switch
switch (token_str[0]) {
case '+':result = operand1 + operand2;
break;
case '-':result = operand1 - operand2;
break;
case '*':result = operand1 * operand2;
break;
case '/':
if (operand2 == 0) {
std::cout << "Error: Cannot divide by zero" << std::endl;
continue; // don't push result, take new input.
} else {
result = operand1 / operand2;
}
break;
// default case not needed as we already checked operator, but
// for error checking, we include it
default:std::cout << "Operator not found" << std::endl;
continue;
}
mystack.push(std::to_string(result));
std::cout << " Push result " << result << " " << std::endl;
} else if ("Y" == token_str || "y" == token_str) {
done = true;
} else if ("stack" == token_str || "s" == token_str) {
std::cout << "stack: ";
std::string stack_dump = stack_to_string(mystack);
std::cout << stack_dump << std::endl;
} else {
std::cout << "Invalid input." << std::endl;
}
}
}
while (!done);
}

Prefix to Infix?

In my class one of our assignments is to convert a prefix equation to infix. After reading that section I still have no idea what I'm doing. The book had some code that will solve a prefix equation when given but I have no idea how it does it or how I would display the infix version. Any help would be appreciated in explaining how this code finds the solution and how I could have it display a infix version.
#include <iostream>
#include <string>
#include <stdlib.h>
#include <sstream>
using namespace std;
int prefixExpr(istream &exprStream);
int main() {
string input;
cout << "Enter prefix expressions to evaluate. \nPress enter after each expression, and press enter on a blank line to quit." << endl;
cout << "Enter a prefix expression to evaluate: ";
getline(cin, input);
while (input.size() != 0){
istringstream exprStream(input);
cout << prefixExpr(exprStream) << endl;
cout << "Enter a prefix expression to evaluate: ";
getline(cin, input);
}
return 0;
}
int prefixExpr(istream &exprStream) {
char ch = exprStream.peek();
while (isspace(ch)) {
ch = exprStream.get();
ch = exprStream.peek();
}
cout << ch << endl;
if (isdigit(ch)) {
int number;
exprStream >> number;
cout << number << endl;
return number;
}
else {
ch = exprStream.get();
int value1 = prefixExpr(exprStream);
int value2 = prefixExpr(exprStream);
switch (ch) {
case '+': return value1 + value2;
case '-': return value1 - value2;
case '*': return value1 * value2;
case '/': return value1 / value2;
default: cout << "Bad input expression";
exit(1);
}
}
}

C++ error when running code

I'm trying to learn C++ and i cant figure a problem out.
My code:
#include <iostream>
using namespace std;
int userContinue = true;
int userContinueString;
int getUserInput() {
int userInput1;
int userInput2;
cout << "Please enter your first number: ";
cin >> userInput1;
cout << endl << "Please enter your second number: ";
cin >> userInput2;
cout << endl << "The result of the two numbers together: " << userInput1+userInput2;
userInput1 = 0;
userInput2 = 0;
return 0;
}
int main()
{
while (userContinue == true) {
getUserInput();
cout << endl << "Would you like to continue? (Y/N): ";
cin >> userContinueString;
if (userContinueString ='Y') {
}
else {
userContinue = false;
}
}
return 0;
}
The code works fine until i input "Y" ant then it keeps looping as shown here: Video
First, make sure you compile your code with some warning switches such as -Wall -Wpedantic. These switches will help you. For instance, in your original code, my compiler prints the following warnings:
prog.cpp:25:28: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (userContinueString = 'Y') {
~~~~~~~~~~~~~~~~~~~^~~~~
prog.cpp:25:28: note: place parentheses around the assignment to silence this warning
if (userContinueString = 'Y') {
^
( )
prog.cpp:25:28: note: use '==' to turn this assignment into an equality comparison
if (userContinueString = 'Y') {
^
==
1 warning generated.
Then, I fix the corresponding line with ==, which was already suggested in the comments. Then, your comparison should be case-insensitive. Finally, you would like to compare character objects with respect to 'y' or 'Y':
#include <cctype>
#include <iostream>
using namespace std;
int userContinue = true;
char /* not int */ userContinueString;
int getUserInput() {
int userInput1;
int userInput2;
cout << "Please enter your first number: ";
cin >> userInput1;
cout << endl << "Please enter your second number: ";
cin >> userInput2;
cout << endl
<< "The result of the two numbers together: " << userInput1 + userInput2;
userInput1 = 0;
userInput2 = 0;
return 0;
}
int main() {
while (userContinue == true) {
getUserInput();
cout << endl << "Would you like to continue? (Y/N): ";
cin >> userContinueString;
if (std::tolower(userContinueString) == 'y') {
} else {
userContinue = false;
}
}
return 0;
}
EDIT. I have improved the answer by taking into account David's comment below. Note the use of #include <cctype> and std::tolower.
EDIT. I have tried improving the answer further by trying to address the "learning C++" comment below:
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
#include <type_traits>
template <class value_t,
typename std::enable_if<std::is_floating_point<value_t>::value,
int>::type = 0>
struct Calculator {
Calculator() = default;
explicit operator bool() {
while (true) {
std::cout << "Valid operations: +, -, *, /, 0 (exit)\n";
std::cout << "What would you like to do: ";
if (!getUserInput(operation)) {
std::cerr << "Wrong input for operation\n";
continue;
}
switch (operation) {
case '0':
return false;
case '+':
case '-':
case '*':
case '/':
break;
default:
std::cerr << "Wrong input for operation\n";
continue;
}
std::cout << "Please enter v1: ";
if (!getUserInput(v1)) {
std::cerr << "Wrong input for v1\n";
continue;
}
std::cout << "Please enter v2: ";
if (!getUserInput(v2)) {
std::cerr << "Wrong input for v2\n";
continue;
}
calculate();
return true;
}
}
friend std::ostream &operator<<(std::ostream &os, const Calculator &c) {
os << "v1 " << c.operation << " v2 = " << c.result;
return os;
}
private:
char operation;
value_t v1, v2, result;
std::string line;
void calculate() {
switch (operation) {
case '+':
return calculate(std::plus<value_t>{});
case '-':
return calculate(std::minus<value_t>{});
case '*':
return calculate(std::multiplies<value_t>{});
case '/':
return calculate(std::divides<value_t>{});
case '0':
return;
}
}
template <class Func> void calculate(Func &&f) { result = f(v1, v2); }
template <class T> bool getUserInput(T &t) {
std::cin >> line;
std::istringstream ss{line};
return (ss >> t) && (ss >> std::ws).eof();
}
};
int main() {
Calculator<double> c;
while (c)
std::cout << c << '\n';
return 0;
}

Program is ignoring input

I'm trying to write a simple brainfuck interpreter in C++. It works great so far, but it ignores the character input command (',').
The Interpreter:
#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;
#define SIZE 30000
void parse(const char* code);
int main(int argc, char* argv[])
{
ifstream file;
string line;
string buffer;
string filename;
cout << "Simple BrainFuck interpreter" << '\n';
cout << "Enter the name of the file to open: ";
cin >> filename;
cin.ignore();
file.open(filename.c_str());
if(!file.is_open())
{
cout << "ERROR opening file " << filename << '\n';
system("pause");
return -1;
}
while (getline(file, line)) buffer += line;
parse(buffer.c_str());
system("pause");
return 0;
}
void parse(const char* code)
{
char array[SIZE];
char* ptr = array;
char c;
int loop = 0;
unsigned int i = 0;
while(i++ < strlen(code))
{
switch(code[i])
{
case '>': ++ptr; break;
case '<': --ptr; break;
case '+': ++*ptr; break;
case '-': --*ptr; break;
case '.':
cout << *ptr;
break;
case ',':
cin >> *ptr;
break;
case '[':
if (*ptr == 0)
{
loop = 1;
while (loop > 0)
{
c = code[++i];
if (c == '[') loop ++;
else if (c == ']') loop --;
}
}
break;
case ']':
loop = 1;
while (loop > 0)
{
c = code[--i];
if (c == '[') loop --;
else if (c == ']') loop ++;
}
i --;
break;
}
}
cout << '\n';
}
The UtraSimple brainfuck code that breaks everything:
,.
Does anyone know what causes it to skip the input character?
I'd be looking at this for a start:
unsigned int i = 0;
while(i++ < strlen(code)) // increments i NOW !
{
switch(code[i]) // uses the incremented i.
The first character that will get processed there will be code[1], not code[0].
So the program ",." will first process . then \0 (end of string) hence there will be no input command , processed.
You can see this if you change the code as follows:
unsigned int i = 0;
while(i++ < strlen(code))
{
cout << "DEBUG [" << i << ":" << (int)code[i] << ":" << code[i] << "]\n";
switch(code[i])
and you'll see:
DEBUG [1:46:.]
DEBUG [2:0: ]
You need to hold off on incrementing i until after you're finished with it.