Semantic issue invalid operands to binary expression ('double' and 'double') - c++

I`m trying to divide any number in .5, if dividing the number in .5 and my remain is 0 the number will raises up to the next. But if not, it will down to the next.
When I try to do that I get a issue in the line 39. Somebody can help me.
Thanks
//
// main.cpp
// Promedio
//
// Created by Oscar Espinosa on 3/27/15.
// Copyright (c) 2015 IPN ESIME Ticoman. All rights reserved.
//
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int ed, cv, qa, em, h, poo;
float prom, red;
string nom, ape;
cout << " Introduce tus datos" << endl
<<"Nombre: ";
getline(cin, nom);
cout << "Apellidos: ";
getline(cin, ape);
cout << "Introduce las siguientes calificaciones" << endl
<< "Ecuaciones Diferenciales: ";
cin >> ed ;
cout << "Calculo vectorial: ";
cin >> cv ;
cout << "Quimica apilcada: ";
cin >> qa ;
cout << "Electricidad y magnetismo: ";
cin >> em;
cout << "Humanidades II: ";
cin >> h;
cout << "Programacion orientada a objetos: ";
cin >> poo ;
prom = (ed+cv+qa+em+h+poo)/6.00;
if (prom%.5 == 0) // Semantic issue invalid operands to binary expression ('double' and 'double')
{
ceil(prom);
red = ceil(prom);
}
else
{
floor(prom);
red = floor(prom);
}
cout << nom << " " << ape << " tu promedio es " << prom << " y se redondea a " << red;
return 0;
}

#Oscar Espinosa you cannot use %(modulus) operator with double values So its showing the error invalid operands in expression.. try using the fmod(x,y) function..it will work

Modulo (%) can only be used with integer values.
You can use fmod but if you meant to work on integer values, perhaps such a trick can help:
if (10*static_cast< int >(prom)%5 == 0)

The issue is pretty clear: you don't define var before the if(var==0). In C++, you need to define the variable before its first use. Pay attention to what the compiler is telling you. In case of g++:
error: 'var' was not declared in this scope
which I think it's pretty explicit!
PS: don't modify the code after an answer, as you end up confusing everyone. In the actual code, you are passing 0.5 as the modulus operator argument. That operator takes an int. You need other way of testing whether a float is a multiple of 0.5. In particular, you should also pay attention to roundoff errors.
Hint: a float x is a multiple of 0.5 if and only if 2*x is an integer. So 2*x - floor(2*x) must be close to zero, i.e. abs(2*x - floor(2*x)) < 1e-12 to avoid floating point errors.
See related question: Checking if float is an integer

Related

C++ "Using Uninitialized Memory.. (variable name) "

This program reads the lines from the text file "penguins.txt" and copies the data into the "FeedingOutput.dat". It worked fine on a different PC but when I run it on my laptop I get the following errors:
Using Uninitialized Memory 'zFeeding'
Using Uninitialized Memory 'zPercent'
Using Uninitialized Memory 'dFeeding'
Using Uninitialized Memory 'dPercent'
Using Uninitialized Memory 'wFeeding'
Using Uninitialized Memory 'wPercent'
The text file "penguins.txt" looks like this:
Zany A 5 4
Den B 4 8
Windi C 5 2.1
Both the .txt and .dat files are in the same directory as the .cpp files.
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
double zFeeding; //Declaring variables
double dFeeding;
double wFeeding;
double zPercent;
double dPercent;
double wPercent;
double zFeedingNew;
double dFeedingNew;
double wFeedingNew;
char filename[50];
string zName, dName, wName, zID, dID, wID;
ifstream penguinInfo; //Allows input and output for the two different files
ofstream dataOutput;
cout << "Enter filename containing penguins information" << endl; //Asking for user to input file name, then opening that file
cin.getline(filename, 50);
penguinInfo.open(filename);
dataOutput.open("FeedingOutput.dat");
dataOutput << showpoint << fixed << setprecision(2); ////formating the output
//this will set the information from penguins.txt to actual variables.
penguinInfo >> zName, zID, zFeeding, zPercent, dName, dID, dFeeding, dPercent, wName, wID, wFeeding, wPercent;
zFeedingNew = zFeeding + (zFeeding * (zPercent / 100)); //equations for new feeding amounts
dFeedingNew = dFeeding + (dFeeding * (dPercent / 100));
wFeedingNew = wFeeding + (wFeeding * (wPercent / 100));
dataOutput << zName << " " << zID << " " << zFeedingNew << " lbs." << endl; //Outputs data to FeedingOutput.dat for Zany
dataOutput << dName << " " << dID << " " << dFeedingNew << " lbs." << endl; //Outputs data to FeedingOutput.dat for Den
dataOutput << wName << " " << wID << " " << wFeedingNew << " lbs." << endl; //Outputs data to FeedingOutput.dat for Windi
penguinInfo.close(); //close files and requires approval to close the program
dataOutput.close();
system("pause");
return 0;
}
I believe this may be a scope issue but I am very new to c++ so I'm not sure what is wrong.
Given
penguinInfo >> zName, zID, zFeeding, zPercent, dName, dID, dFeeding, dPercent, wName, wID, wFeeding, wPercent;
According to the operator precedence, operator >> has higher precedence than operator, and it's just same as
(penguinInfo >> zName), zID, zFeeding, zPercent, dName, dID, dFeeding, dPercent, wName, wID, wFeeding, wPercent;
i.e. only zName is set as penguinInfo >> zName.
You can change it to
penguinInfo >> zName >> zID >> zFeeding >> zPercent >> dName >> dID >> dFeeding >> dPercent >> wName >> wID >> wFeeding >> wPercent;
The problem is that the comma operator doesn't do what you think it does. It simply discards the left and side, and continues with the right hand side:
In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing) (until C++17).
Most importantly, it does not fill all the variables used in the comma expression with anything. Thus, your variables remain uninitialized (since you didn't initialize them above).
What you actually want to do is to chain the >> operator just like you would the << operator. That would look like this instead:
penguinInfo >> zName >> zID >> zFeeding >> zPercent >> dName >> dID >> dFeeding >> dPercent >> wName >> wID >> wFeeding >> wPercent;

C++ function to read an integer number from the keyboard

I'm trying to write in C++ a function (leggiInteroEstrIncl) that prompts the user to type by keyboard an integer number included in a given range (between minimo and massimo).
Following is the function I wrote and then a statement, in the main(), to invoke it:
#include <iostream>
using namespace std;
int leggiInteroEstrIncl(string stringaDaStampare, int minimo, int massimo) {
int numInserito = 0;
bool errore = false;
do {
errore = false;
cout << stringaDaStampare << " (un numero intero compreso tra " << minimo
<< " e " << massimo << " estremi inclusi): ";
try {
cin >> numInserito;
} catch (...) {
errore = true;
cout << "Hai inserito un numero non valido, prova ancora" << endl;
}
if (errore == false && (numInserito < minimo || numInserito > massimo)) {
errore = true;
cout << "Hai inserito un numero al di fuori dell'intervallo richiesto: "
<< minimo << " <-> " << massimo << endl;
}
} while (errore);
return numInserito;
}
int main() {
int number = 0;
number = leggiInteroEstrIncl(
"Inserire la cifra in Yen da ripartire in banconote e monete", 1, 30000);
system("pause");
return 0;
}
If I type a valid integer number which is not included in the specified range, this piece of software works and asks the user to type again, but if I type something which is not a number, for example the word "hello", this software goes in a sort of loop and doesn't stop to ask the user to type again.
Could you please tell me what is wrong with it?
Thank you
You can use std::string to get input:
string insertio;
cin >> inserito;
and then use one of this function:
http://en.cppreference.com/w/cpp/string/basic_string/stol
which throws proper exception if there isn't a number in string.
If you need to check more solutions, check this one:
How to determine if a string is a number with C++?
This
cin >> numInserito;
attempts to read in a number and nothing else.
It will succeed with a number, as you have observed.
With a non-number it will fail, but not in a way to trigger the catch part.
It will instead just not read anything in and especially it will leave the non-number in the input stream.
If you then continue trying to read in a number, it will continue failing.
When reading in a number fails you need to read in whatever there is and probably ignore it.
In order to ignore the non-number, read it in as a string and do nothing with it
(as described in the answer by BartekPL):
string insertio;
cin >> inserito;

2 identical codes, get error at one

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

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;

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