Reputation: 23
I'm a beginner and am stuck on such a simple problem whilst working through Stroustrup's Principles and Practices.
Using only basic elements
#include "std_lib_facilities.h"
int main()
{
double highest = 0;
double lowest = 100;
int i=0;
double sum = 0;
vector <double> inputlist;
double input;
string unit;
cout<<"Type in a number followed by it's unit \n";
while(cin>>input>>unit){
inputlist.push_back(input);
sum += inputlist[i];
if (input >= lowest && input <= highest){
cout<<input<<" \n";
++i;
}
else if (input < lowest){
lowest = input;
cout<<"\nLowest Number so far \n"<<lowest;
++i;
}
else if (input > highest){
highest = input;
cout<<"\nHighest number so far \n"<< highest;
++i;
}
else
cout<<"Lowest is: \n"<<lowest<<"\n\n Highest is: \n"<<highest<<" \n\n and the total is: \n"<<sum;
if (unit == "ft", "m", "in","cm")
cout<<unit<<"\n";
else
cout<<"cannot recognize unit";
}
keep_window_open();
return 0;
}
I need the program to show the user the sum and highest and lowest value when the character "|" is entered. Problem is: i need this entered where the Integer value should be entered.
NOTE: I don't know much about conversions but tried a few and they didn't work.
Upvotes: 1
Views: 243
Reputation: 5198
Summing meters with inches does not make much sense. Therefore, you should consider to translate the units into scaling factors. You could use a map to get the scaling factors. Even if this is somewhat overshoot you might use regular expressions to parse the user input. If the regex does not match you can test for stuff like "|". In the new c++-standard (http://en.wikipedia.org/wiki/C%2B%2B11) a regex library is defined for this purpose. Pityingly, the g++ regex library is buggy. But you can use boost (http://www.boost.org/doc/libs/1_54_0/libs/regex/doc/html/boost_regex/). Here is an example:
#include <iostream>
#include <vector>
#include <map>
#include <boost/regex.hpp> //< Pittyingly std::regex is buggy.
using namespace std; ///< Avoid this in larger projects!
using namespace boost;
int main() {
const string strReFloat("([-+]?[[:digit:]]*\\.?[[:digit:]]+(?:[eE][-+]?[[:digit:]]+)?)");
const string strReUnit("([[:alpha:]]+)");
const string strReMaybeBlanks("[[:blank:]]*");
const string strReFloatWithUnit(strReMaybeBlanks+strReFloat+strReMaybeBlanks+strReUnit+strReMaybeBlanks);
const regex reFloatWithUnit(strReFloatWithUnit);
const map<const string,double> unitVal= {
{"m", 1.0},
{"in", 0.0254},
{"ft", 0.3048},
{"cm", 0.01}
};
double highest = 0;
double lowest = 100;
int i=0;
double sum = 0;
vector <double> inputlist;
double input;
double unitToMeter;
string unit;
string str;
while( (cout<<"\nType in a number followed by it's unit \n", getline(cin,str), str != "") ){
smatch parts;
if( regex_match(str,parts,reFloatWithUnit) ) {
unit = parts[2].str();
auto found = unitVal.find(unit);
if( found != unitVal.end() ) {
cout<<unit<<"\n";
input = found->second * atof(parts[1].str().c_str());
} else {
cout << "Unit \"" << unit << "\" not recognized. Using meters.\n";
}
inputlist.push_back(input);
sum += inputlist[i];
if (input >= lowest && input <= highest){
cout<<input<<" \n";
++i;
}
else if (input < lowest){
lowest = input;
cout<<"\nLowest Number so far \n"<<lowest;
++i;
}
else if (input > highest){
highest = input;
cout<<"\nHighest number so far \n"<< highest;
++i;
}
} else if( str == "|" ) {
cout << "sum:" << sum << "\n";
} else {
cout << "Input not recognized.\n";
}
}
return 0;
}
Upvotes: 0
Reputation: 24205
Read the value with string. if it doesn't match | convert it to double using the following function:
double toDouble(string s)
{
int sign = 1, i=0;
if (s[0]=='-')
sign = -1, i=1;
double result = 0, result2 = 0;
for (; i < s.size(); i++)
if (s[i] == '.')
break;
else
result = result * 10 + (s[i] - '0');
for (i = s.size()-1 ; i>=0 ; i--)
if (s[i] == '.')
break;
else
result2 = result2 / 10 + (s[i] - '0');
if (i>=0)
result += result2/10;
return result * sign;
}
Upvotes: 0
Reputation: 42083
If I understood you correctly, you want to read int
from std::cin
, but:
int i;
if (std::cin >> i) {
...
doesn't suite your needs since there might be '|'
sign as a signal for termination of reading.
Here's what you could do: read input word by word (std::string
) and parse these words separately using temporary std::istringstream
:
std::string word;
if (std::cin >> word) {
if (word == "|")
...
// else:
std::istringstream is(word);
int i;
if (is >> i) {
// integer successfully retrieved from stream
}
}
just #include <sstream>
Upvotes: 3