Trouble using a series of getlines to extract elements from user input - c++

Sorry for the simple question, but I couldn't find an already available answer elsewhere.
I am building a fractional calculator that can either add, subtract, divide, or multiply two fractions(e.g 4/3 + 5/2). Firstly however, I need to parse out different elements of the user's input, like the arithmetic operator, and the numerator and denominators of the two fractions and store those elements in order to manipulate them down the line.
I thought of using a series of getline(string) while altering the default delimiter to discard whitespace and / signs. However, when I try to execute my program, there seems to be issues with getline(string).
Might somebody be able to point out my surely amateur mistake? The compiler isn't throwing any errors, so I'm a bit lost on what it might be.
EDIT: I'VE SINCE BEEN ABLE TO RESOLVE THE ISSUE THANKS TO HELP. THANK YOU EVERYONE
#include <string>
#include <iostream>
using namespace std;
int main()
{
string numeratorfirst;
string denominatorfirst;
string arithoperator;
string numeratorsecond;
string denominatorsecond;
cout << "Enter the two fractions and the operator you want to use(IE: 3/4 + 4/6): ";
getline(cin, numeratorfirst, '/');
getline(cin, denominatorfirst, ' ');
getline(cin, arithoperator);
getline(cin, numeratorsecond, '/');
getline(cin, denominatorsecond, ' ');
cout << " " << endl;
cout << "Your fraction is: " << numeratorfirst << "/" << denominatorfirst << " " << arithoperator << " " << numeratorsecond << "/" << denominatorsecond << endl;
system("pause");
return 0;
}

It might be easier using scanf():
int numeratorfirst;
int denominatorfirst;
char arithoperator;
int numeratorsecond;
int denominatorsecond;
cout << "Enter the two fractions and the operator you want to use(IE: 3/4 + 4/6): ";
int tokens = scanf("%d/%d %c %d/%d", &numeratorfirst, &denominatorfirst,
&arithoperator, &numeratorsecond, &denominatorsecond);
if (tokens != 5)
return 1;
This works, and it rejects invalid inputs like "foo/bar + baz/qux".
If you want a "more C++ like" solution, try this:
int numeratorfirst, denominatorfirst, numeratorsecond, denominatorsecond;
char slashfirst, slashsecond;
char arithoperator;
cout << "Enter the two fractions and the operator you want to use(IE: 3/4 + 4/6): ";
cin >> numeratorfirst >> slashfirst >> denominatorfirst >> arithoperator
>> numeratorsecond >> slashsecond >> denominatorsecond;
if (!cin || slashfirst != '/' || slashsecond != '/')
return 1;

Related

Homework Beginner C++: Unable to perform Type Casting during addition of integers

In order to help us understand type casting in C++, we are required to perform addition of two int's as shown below. If we provide two int's as 4 and 5 respectively, the output should be 4 + 5 = 9.
I tried to follow this type casting tutorial without any success. Could someone please provide me a hint or something?
Quoting the assignment verbatim.
Your friend wrote a program called an adder. The adder is supposed to take two numbers inputted by a user and then find the sum of those numbers, but it’s behaving oddly.
Your first task is to figure out what is wrong with the adder. Your second task is to fix it.
Hint(s) to identify the problem
Try entering 1 and 1. You expect the output to be 2 but you get 11 instead. Similarly, if you enter 3 and 4, you expect the output to be 7 but you get 34. Remember, string concatenation also uses the + operator.
Hint(s) to identify the solution
The + operator functions differently based on the type of data that comes before and after it. What data types will cause the + operator to calculate a mathematical sum? What data type is present in the program now? How do you convert from one data type to another? Check out the Type Casting page for some idea
#include <iostream>
using namespace std;
int main() {
string num1;
string num2;
cout << "Type the first whole number and then press Enter or Return: ";
cin >> num1;
cout << "Type the second whole number and then press Enter or Return: ";
cin >> num2;
string sum = num1 + num2;
cout << ( num1 + " + " + num2 + " = " + sum ) << endl;
return 0;
}
The problem with the code is that it is performing string concatenation when it needs to perform arithmetic addition instead. So you need to get the user's input into numeric variables, not strings. The assignment even alludes to this.
However:
Check out the Type Casting page for some idea
That is bad advice for this task, as you can't solve the problem with type casting.
You need to either:
Change the code to use int variables instead of string variables. This is the preferred solution, eg:
#include <iostream>
using namespace std;
int main() {
int num1;
int num2;
cout << "Type the first whole number and then press Enter or Return: ";
cin >> num1;
cout << "Type the second whole number and then press Enter or Return: ";
cin >> num2;
int sum = num1 + num2;
cout << num1 << " + " << num2 << " = " << sum << endl;
return 0;
}
Otherwise, if you want to continue using string variables, you need to convert (not type cast!) their values into int values at runtime, and then convert back afterwards, eg:
#include <iostream>
#include <string>
using namespace std;
int main() {
string num1;
string num2;
cout << "Type the first whole number and then press Enter or Return: ";
cin >> num1;
cout << "Type the second whole number and then press Enter or Return: ";
cin >> num2;
int sum = stoi(num1) + stoi(num2);
cout << ( num1 + " + " + num2 + " = " + to_string(sum) ) << endl;
return 0;
}
if you typecast a character or string it get's converted into its equivalent ASCII value , either you need to use stoi or subtract from '0' for every digit position(a bit repeatitive work) go with stoi

How to add commas to a number if it's declared as a double?

lets say I want the user to input a number and I want that number to cout with commas.
Example.
double attemptOne;
cout << "Enter a number: ";
cin >> attemptOne; //user inputs 10000.25
cout << endl << attemptOne; //I want to cout 10,000.25
I am new in c++ so please help me with out
I am not talking about the decimal to be changed to a comma but for the program to know when the number is bigger than 999 to add commas like 1,000.25 10,000.25 100,000.25. I also do NOT want to use local
Maybe, since you need a string, you can read a string as well, and just parse it, adding commas every 3rd digit from the decimal point, or from the end if no decimal point exists:
#include <iostream>
#include <string>
int main()
{
std::string attemptOne;
std::cout << "Enter a number: ";
std::cin >> attemptOne;
size_t dec = attemptOne.rfind('.');
if (dec == std::string::npos)
dec = attemptOne.size();
while (dec > 3)
attemptOne.insert(dec -= 3, 1, ',');
std::cout << attemptOne << std::endl;
}

(C++) Trouble excluding alphanumeric input into application

so this is one of the first bits of code I am trying to write without too much direction, however I seem to have hit a wall. I am attempting to write a very basic "MPG" application and one thing I have come to find is that when the application asks for user input it allows inputs such as "2d" or any alphanumeric input and it continues to operate as long as the digit is first. For example "2d will work but "d2" will not, and the application will carry on as if the letter is not there. ex. 2d/2=1. Here's the code.
#include <iostream>
#include <ctype.h>
int main()
{
float a, b;
char again = 'Y';
std::cout << "After several hours on the road you wonder what your gas mileage must have been..." << "\n";
while (again == 'y' || again == 'Y')
{
std::cout << "How much gas did you have in your tank to start with?" << "\n";
while (!(std::cin >> a))//cin for float a
{
std::cout << "Your input must be a number...1" << "\n";
std::cin.clear();
std::cin.ignore(1000000, '\n');
}
if (a > 0)
std::cout << "How many miles did you travel?" << "\n";
while (!(std::cin >> b))//cin for float b
{
std::cout << "Your input must be a number...2" << "\n";
std::cin.clear();
std::cin.ignore(1000000, '\n');
}
if (b > 0)
std::cout << "You have obtained an whopping " << b / a << " miles to the gallon!" << "\n" << "\n";
std::cout << "Would you like to try again? (Y/N): ";
std::cin >> again;
}
}
By default, numeric formatting starts with skipping whitespace and stops reading characters as soon as one character not matching the format of the read type is encountered. If a number could be read before such a character is encountered the read succeeds.
That applied to your example of entering "2d" means that 2 is successfully read as number and the next character to be read is d. If you want to catch that situation as an error, you can check what the next character in the stream is. If you require individual numbers to be read on lines without any spaces trailing the value, you can simply do something like this:
while (!(std::cin >> a) || std::cin.peek() != '\n') {
// ...
}

How I can manage to keep white space in my String from user input

I'm coding a little console application in C++ and in it I take a string from the user:
cin >> themainstring;
int si = 0;
while (themainstring[si] != '+' || themainstring[si] != '-' ||
themainstring[si] != '*') {
if (themainstring[si] == '+' || themainstring[si] == '-' ||
themainstring[si] == '*') {
lmnopt = themainstring[si];
break; // while
}
si++;
}
int strlenthestring = themainstring.size();
lmnop1 = themainstring.substr(0, si);
lmnop2 = themainstring.substr(si + 1, strlenthestring);
So for example, when I give this input:
ilove+programming
I want to try and cut the string when I see +, - and *. which works fine.
However I want my code to do the same when I input:
ilove + programming (white spaces after and before arithmetical operator)
I have messed around with the WS but I couldn't understand the logic.
Actually the main problem of mine is about C++'s space logic. Why it thinks the space will explode the string input?
I'm not sure I've understood this question completely correctly, however I thought I'd pitch in with some help.
First off, when it comes to looking through strings, C++ has a great set of functions as standard that does that. Point your browser to: Basic String Library.
This contains all the functions you can carry out on a string in C++.
Secondly, something else you need to be aware of, is that you are using std::cin to read user input from the keyboard. By default, cin ignores white spaces, so for example, the following code:
string inputString;
cin >> intputString;
cout << "Input String is: " << inputString << endl;
and let's assume you entered Hello World in as your user input, the program would only output "Hello"
So what you need to do is to use getline. Which allows for whitespaces in your user inputs. And you use it as follows:
std::getline(cin, inputString);
So to give an example where it all gels together:
#include <iostream>
#include <sstream> // for istringstream
#include <string>
using namespace std;
int main(int argc, char * argv[])
{
string inputString;
cout << "Please Enter String: ";
getline(cin, inputString);
cout << "\n" << endl;
cout << "InputString is: " << inputString << endl;
// So you can do something like this
string searchTerm("+");
// Find first of is an operating you can carry out
// on a string so you don't have to use loops.
cout << "Position: " << inputString.find_first_of(searchTerm) << endl;
int pos = inputString.find_first_of(searchTerm);
string part1 = inputString.substr(0, pos);
string part2 = inputString.substr(pos + 1, inputString.length());
cout << "Position of + is " << pos << endl;
cout << "part 1 is: " << part1 << endl;
cout << "part 2 is: " << part2 << endl;
}
Now I know I've only done this with the + sign, but it should serve as a starting point to getting to where you want to be.
Hope all this helps.

C++ How to check an input float variable for valid input

I'm writing a program that acts as a calculator; based on the character input by the user it performs a certain operation. The structure of the program seems to work fine, but I'd like to be able to check for erroneous input. After receiving the float variable, is there any way to check if it does not contain any characters other than digits and decimals? I've tried isdigit, and this:
if (!(cin >> x)) {
cout << "You did not enter a correct number!" << endl;
return;
}
But nothing seems to be working.
Here is a sample of one of the simple operation functions I'm using:
void Add(){
float x = 0, y = 0, z = 0;
cout << "Please enter two numbers you wish "
<< "to add separated by a white space:" << endl;
cin >> x >> y;
z = x+y;
cout << x << " + " << y << " = " << z << "." << endl;
return;
}
You test the state of the stream:
float x, y;
if (std::cin >> x >> y) {
// input extraction succeeded
}
else {
// input extraction failed
}
If this isn't working for you, then you need to post the exact code that isn't working.
To detect erroneous string input where you expected a number, C++ doesn't automatically know what you want, so one solution is to first accept your input as strings, validate those strings, then if valid, only then convert the strings to float numbers using the atof() function.
The standard string class has a function called find_first_not_of() to help you tell C++ which characters you consider valid. If the function finds a character not in your list, it will return the position of the bad character, otherwise string::npos is returned.
// add.cpp
#include <iostream>
#include <string>
#include <cstdlib> // for atof()
using namespace std;
void Add()
{
cout << "Please enter two numbers you wish "
<< "to add, separated by a white space:"
<< endl;
string num1, num2;
cin >> num1;
if( num1.find_first_not_of("1234567890.-") != string::npos )
{
cout << "invalid number: " << num1 << endl;
return;
}
cin >> num2;
if( num2.find_first_not_of("1234567890.-") != string::npos )
{
cout << "invalid number: " << num2 << endl;
return;
}
float x = 0, y = 0, z = 0;
x = atof( num1.c_str() );
y = atof( num2.c_str() );
z = x+y;
cout << x << " + " << y << " = " << z << "." << endl;
}
int main(void)
{
Add();
return 0;
}
One possibility would be to read the input as a string, then use boost lexical_cast to convert to floating point. lexical_cast only considers the conversion successful if the entire input converts to the target -- otherwise, it'll throw a bad_lexical_cast exception.
Another idea would be to test the input against a regex. An example regex for a float could be
-?[0-9]+([.][0-9]+)?
This method would also make it easier to refine the matching mechanism by only modifying the regex, and you could map multiple regular expressions against different types of input, for example an integer could then be expressed as
-?[0-9]+
and so on. Keep in mind however, that this only tests if the input is a valid format, it still requires a numerical conversion afterwards (I prefer boost::lexical_cast).
(You can also try it out with http://gskinner.com/RegExr/)