2 identical codes, get error at one - c++

I added comments to the code, do I have a compiler issues? I can't figure it out, I tried looking on google and the book but I cant figure out why the first half of code only accepts the input with space between the number and unit and second code accepts the number and unit together.
I'm using code blocks. So far I tried closing it and opening it again.
int main(){
constexpr double dollar_to_euro = 0.91;
constexpr double dollar_to_yen = 117.07;
constexpr double dollar_to_pounds = 0.70;
double sum = 1;
char curr = '\0'; // tried replacing '\0' with '0' and ' '
cout << "Please enter sum, followed by currency for conversion.\n"
<< "U for dollar, E for euro, Y for yen and P for pounds.\n";
cin >> sum >> curr; // This is my issue, it does not want to accept "sumcurr" together, it only accepts it if theres space in between
// yet on the second code for inches or centimeters it does accept them being together. Look down.
// For example entering "5 E" works, yet "5E" does not work.
if(curr=='E')
cout << "The amount " << sum << " euro is " << sum/dollar_to_euro << " dollars\n";
else
cout << "GOD DAMMIT !!!!\n";
constexpr double cm_per_inch = 2.54;
double len = 1;
char unit = '\0';
cout << "Please enter length followed by unit.\n";
cin >> len >> unit; // Over here it works, this is an example from a book. Entering "5i" works.
if(unit=='i')
cout << len << " in == " << cm_per_inch*len << "cm.\n";
else
cout << "Wrong input !\n";
}

The problem here is that E/e is valid in a floating point number but 5E/5e is not a valid floating point number as you need a value after the E/e. So when you enter 5e the input for sum fails because of the invalid syntax where 5e0 would work. If you use anything other than E/e then it will work like your second example.
For more information on the format of floating point numbers see: Cppreference floating point literal

Related

C++ Finding square root without sqrt function loop glitching

So I am making this as a homework assignment. I understand that there are so many ways that this code could be more efficient and accurate but this is the way my professor wants it done.
I am having problems with the loop. When I ask for the square root of 67 it does find it but it loops the correct answer 3 times.
Enter a value to be square rooted:
67
33.5
guess = 17.75
guess = 10.7623
guess = 8.49387
guess = 8.19096
guess = 8.18535
guess = 8.18535
guess = 8.18535
The program took 7 guess to find an estimation.
When I try to find the square root of 5 it finds it but continues to loop indefinitely
using namespace std;
int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;
cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess1 = squarenumber/2;
cout << guess1 << endl;
do
{
guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));
guess1 = guess2;
cout << "guess = " << guess2 << endl;
numofguess = numofguess + 1;
} while ((guess2 * guess2) > squarenumber);
cout<< "The program took "<< numofguess <<" guess to find an estimation.";
return 0;
}
I think that what you are missing is a proper exit condition.
Your code is written to loop indefinitely until the guess is "perfect".
You should have an exit condition checking if current guess is the same as previous guess, which obviously means that you won't do any better.
Here is my suggestion based on your code :
using namespace std;
int main()
{
double guess2;
double squarenumber;
double guess1;
int numofguess = 0;
cout << "Enter a value to be square rooted: " << endl;
cin >> squarenumber;
guess2 = guess1 = squarenumber/2;
cout << guess1 << endl;
const double epsilon = squarenumber * 1E-6;
do
{
guess1 = guess2;
guess2 = (guess1 - (((guess1 * guess1) - squarenumber)/(2* guess1)));
cout << "guess = " << guess2 << endl;
numofguess = numofguess + 1;
} while ((guess2 * guess2) > squarenumber && fabs(guess2-guess1) > epsilon);
cout<< "The program took "<< numofguess <<" guess to find an estimation.";
return 0;
}
Mickaël C. Guimarães's answer is basically correct, check for an episolon value (absolute difference from the correct answer and your answer). But the "(guess2 * guess2) > squarenumber" should be dropped completely. That's because the value could in theory overshoot and be too low. The algorithm actually goes upwards if the value is too low. e.g. if you want SQRT(25) and your "guess1" prediction is way too low at 2, then guess2 would equal
(2 - (((2 * 2) - 25)/(2* 2))) = 7.25;
And on the next iteration then falls to 6.725624, so heads in the right direction. Low values actually get boosted up and eventually approach the target. By stopping if the value drops below the true SQRT then you might get "false positives" where too low values are accepted as accurate enough.
The times when the system got "stuck" were basically like the story Acchiles and the Tortoise. At each step, the system was dividing the remaining distance to go by some amount, but the change was therefore smaller each step, and could in theory never converge on the exact value, therefore you decide how much accuracy you want so that it finishes in a set time.
Additionally, the issue where the system seemed to take too many steps to converge is because floating point numbers are stored in higher precision, but cout has limited display precision. You can control that by sending setting values to cout before the print commands:
std::cout << std::fixed; // force all values to show to the same decimals
std::cout << std::setprecision(6); // set how many places to show
These code can be streamed to cout in one command before the value to print as well:
std::cout << std::fixed << std::setprecision(6) << "guess = " << guess2 << 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') {
// ...
}

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

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;

super simple currency converter switch acting oddly?

This was an exercise from Principles and Practice Using C++ to make a basic currency converter using if checks then to remake it with switches. Everything runs pretty good except or my middle switch. It doesn't seem to work like the rest of the program. Every other one is fine with me entering in data like 111y, 111p but when working with euros it NEEDS a whitespace or else it will go to the default switch. I did a break point and currency is not being set to e or E and it's only with the euros!
I hope it isn't anything too silly, but it's got me confused Bjarne doesn't explain this one :P I don't have #include iostream in the code because it's all handled with *std_lib_facilities* Just wanted to say that before someone points it out XD
#include "std_lib_facilities.h"
using namespace std;
int main()
{
double dollar = 0;
char currency = ' ';
const double yen = 0.010;
const double euro = 1.31;
const double pound = 0.65;
double sum = 0;
cout << "Please enter amount and Y for yen or E for Euro or P for pound.\n";
cin >> dollar >> currency;
switch(currency)
{
case 'Y': case'y':
{
sum = dollar * yen;
cout << dollar << " is equal to " << sum << " yen.\n";
break;
}
case 'E': case'e':
{
sum = dollar * euro;
cout << dollar << " is equal to " << sum << " euro.\n";
break;
}
case 'P': case'p':
{
sum = dollar * yen;
cout << dollar << " is equal to " << sum << " pound.\n";
break;
}
default:
cout << "Wrong values...\n";
break;
}
keep_window_open();
return 0;
}
Since dollar is a double, the E or e gets interpreted as part of the exponent of the number (as in 2e-2) when you extract it. Since there are no digits after it, the extraction does not complete and cin goes into the fail state. The read of currency is then skipped, never changing it from the initial value of ' '. When you enter a space, the extraction of dollar ends at the space and currency is read as expected.
To fix it, you could try several things. You could require a space between the amount and the currency indicator. You could read it in as a string and attempt to parse it yourself. You could pick a different symbol for euros.
In any case, you should check the state of the cin after you're done reading from it.

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/)