1

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.

1
  • 1
    Just keep input as a string, test for "|" and convert to integer afterwards. Plenty of examples on the latter here on SO. Commented Sep 25, 2013 at 11:47

3 Answers 3

3

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>

Sign up to request clarification or add additional context in comments.

1 Comment

thank you, this works great. if you could very briefly explain how this i'd be very greatful!
0

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;
}

Comments

0

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.