Thread: Finding mix & max of a calculated variable from an input file

  1. #1
    Registered User
    Join Date
    May 2019
    Posts
    23

    Finding mix & max of a calculated variable from an input file

    I'm currently learning about fstream in my beginner C++ class. I have an assignment where I am asked to do various things. I have a file that I read the name of the cities and their affiliated cost of living including groceries, housing, etc. I use the cost of living to calculate the Index cost of the city for the whole input file I was given.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    
    using namespace std;
    
    
    double computations(double&, double&, double&, double&, double&, double&);
    
    
    int main()
    {
        string city;
        double groceries, housing, utilities, transportation, health, misc, index;
        ifstream inFile;
                        
        //open file; if fails exit program
        inFile.open("C:\\Users\\Teddy Kim\\Downloads\\costIndex.txt");
        if(inFile.fail())
        {
            cout << "File does not exist" << endl;
            exit(100);
        }
        
        while (!inFile.eof())
        {
            getline(inFile, city);
            inFile >> groceries >> housing >> utilities >> transportation >> health >> misc;
            index = computations(groceries, housing, utilities, transportation, health, misc);
            cout << index << endl;
            string tempstr; getline(inFile, tempstr); system("pause");
    
    
        }
    
    
    
    
    }
    
    
    double computations(double& g, double& h, double& u, double& t, double& he, double& m)
    {
        double total;
        total = 0.13 * g + 0.29 * h + 0.10 * u + 0.12 * t + 0.12 * he + 0.24 * m;
        return total;
    }
    Essentially, I have index set up as the calculation using the computations function for the cost of each city. The problem is now that I have to find the lowest and highest index value from the given set of data I just calculated. I have absolutely no clue on how to do that for a variable calculation based on an input file. I also have to be able to label the highest and lowest index with the affiliated string of city name. I won't show the whole input file because theres over a hundred lines but it looks like this and just repeats for different cities.

    Asheville, NC
    104.6 97.8 113.1 94.2 104.7 100.6
    I have not learned anything about arrays or vectors yet so I am not allowed to utilize those concepts. Can someone give me a hint or point me in the right direction on how to calculate the lowest & highest index as well as output the city name that is attached with the value?

    Thank you!

  2. #2
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    maybe have a max_index and a min_index then test if the index you just calculated was above max or below min

  3. #3
    Registered User
    Join Date
    May 2019
    Posts
    209
    @cooper1200's on the right track.

    The secret is here:

    Code:
       
        while (!inFile.eof())
        {
            getline(inFile, city);
            inFile >> groceries >> housing >> utilities >> transportation >> health >> misc;
            index = computations(groceries, housing, utilities, transportation, health, misc);
            cout << index << endl;
    
            string tempstr; getline(inFile, tempstr); system("pause");
     
     
        }
    However, you need to fashion a pair doubles, something like max_index and min_index. Initialize the max_index to zero (I assume there are no negative index values). Initialize the min_index to the max of a double (look up numeric limits in C, specifically DBL_MAX and DBL_MIN). If negative index is possible, then initialize max_index to the minimum double.

    Inside the loop above, for every index you calculate, check that against current value of max_index and min_index. If the current max_index is less than the calculated index, remember it by storing that in max_index. The same (in reverse) is applied to min_index.

    After the loop, simply cout the values.

  4. #4
    Informer -Adrian's Avatar
    Join Date
    Jan 2013
    Posts
    816
    Quote Originally Posted by Niccolo View Post
    Initialize the min_index to the max of a double (look up numeric limits in C, specifically DBL_MAX and DBL_MIN)
    In C++ one can use:
    Code:
    #include <limits>
    
    double max_value = std::numeric_limits<double>::max();

  5. #5
    Registered User
    Join Date
    May 2019
    Posts
    23
    Thank you for the input all.

    Unfortunately I have not learned limits yet in my class so I am unable to utilize them.

    I think I can still take the advice given by Niccolo and cooper by utilizing the same concept except initializing my mix/max index value to be the first index and using an equality operator after for each index in the loop using >/< and replacing the value respectively. I'll give it a shot.

    Quick question. Doing the above would allow me to output min_input & max_output after the loop is finished but I think that would only output the number itself of the lowest and highest. How do I output the string of the city where I have getline() as well?

  6. #6
    Registered User
    Join Date
    May 2019
    Posts
    23
    I got it for the max option.. I'm not sure how to do it for the min option?

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    
    using namespace std;
    
    
    double computations(double&, double&, double&, double&, double&, double&);
    
    
    int main()
    {
        string city;
        double groceries, housing, utilities, transportation, health, misc, index;
        double max = 0;
        double min;
        ifstream inFile;
        ofstream outputFile;
                        
        //open file; if fails exit program
        inFile.open("C:\\Users\\Teddy Kim\\Downloads\\costIndex.txt");
        outputFile.open("index.txt");
        if(inFile.fail())
        {
            cout << "File does not exist" << endl;
            exit(100);
        }
        
        while (!inFile.eof())
        {
            getline(inFile, city);
            inFile >> groceries >> housing >> utilities >> transportation >> health >> misc;
            index = computations(groceries, housing, utilities, transportation, health, misc);
            string tempstr; getline(inFile, tempstr);
            outputFile << city << " " << index << endl;
            
            if (index > max)
            {
                max = index;
            }
            
            
            if (index <= min)
            min = index;
            
        }
        outputFile.close();
        cout << max << endl;
        cout << min;
        
        
    
    
    
    
    }
    
    
    double computations(double& g, double& h, double& u, double& t, double& he, double& m)
    {
        double total;
        total = 0.13 * g + 0.29 * h + 0.10 * u + 0.12 * t + 0.12 * he + 0.24 * m;
        return total;
    }
    I initialized double max = 0 which was easy since the highest index will be above 0. However, I wasn't sure what to initialize min to. Right now as the code runs.. it doesn't do min correctly because I'm not sure what to initialize it to. Is there anyway for me to intialize min to the first index calculated somehow? Since the index is calculated in a loop I'm not sure how to set double min = first index calculated. Also, how am I suppose to be able to output the string aka the city associated with the lowest and highest index along with their value? I can only seem to output the values here
    Last edited by underpressure; 06-15-2019 at 05:17 PM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,231
    Earlier, you wrote:
    I think I can still take the advice given by Niccolo and cooper by utilizing the same concept except initializing my mix/max index value to be the first index
    Do that and it will solve your min issue. If you wish to avoid code repetition without moving code into a function, then you could create a bool variable to determine whether or not it is the first iteration (and therefore the first index), and with that set the initial value of min and max.

    By the way, instead of this:
    Code:
    while (!inFile.eof())
    {
        getline(inFile, city);
    Write:
    Code:
    while (getline(inFile, city))
    {
    The reason is that the call to eof() will only evaluate to false after the end has been reached or a failed read, but you only want to keep looping until the read has been reached or a failed read. EDIT: actually, you need to && this with your inFile >> etc line too.

    Also, there's no point declaring your input/output streams then immediately opening them. Declare and open at one go, e.g.,
    Code:
    ofstream outputFile("index.txt");
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    May 2019
    Posts
    23
    Quote Originally Posted by laserlight View Post
    Earlier, you wrote:

    Do that and it will solve your min issue. If you wish to avoid code repetition without moving code into a function, then you could create a bool variable to determine whether or not it is the first iteration (and therefore the first index), and with that set the initial value of min and max.

    By the way, instead of this:
    Code:
    while (!inFile.eof())
    {
        getline(inFile, city);
    Write:
    Code:
    while (getline(inFile, city))
    {
    The reason is that the call to eof() will only evaluate to false after the end has been reached or a failed read, but you only want to keep looping until the read has been reached or a failed read. EDIT: actually, you need to && this with your inFile >> etc line too.

    Also, there's no point declaring your input/output streams then immediately opening them. Declare and open at one go, e.g.,
    Code:
    ofstream outputFile("index.txt");
    Thank you. Makes sense to make it more efficient rather than separate.

    Do you have any idea on how to make my min code work? I declared min = 100 since I know that there are values lower than 100 and I get the correct answer. However, I don't feel as if this is the right technical code to do and I would want to write the code to assume that I do not know what values I may have.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,231
    You already have the answers to that in posts #3 and #4, but you can't use them. So, if you must use that method, then you have to look up what's the largest possible value of that type, set your min to that, then hope your teacher doesn't decide to compile your program targeting a system with something different from that value just to mark you down for it.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    May 2019
    Posts
    209
    If you can't use the formal limits, you could choose an arbitrarily large extreme, like 1000000.0, or1 billion, for min. Similar for max ( -1000000.0 ) or more.

    As to the rest of the data, every time you set min or max, store that line's data in related values, like min_groceries, min_house, max_groceries, max_housing, etc.

  11. #11
    Registered User
    Join Date
    May 2019
    Posts
    23
    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    
    
    using namespace std;
    
    
    //function prototype
    double computations(double, double, double, double, double, double);
    
    
    int main()
    {
    	//declare variables
    	string city;
    	double groceries, housing, utilities, transportation, health, misc, index;
    	int flag;
    	
    	//max is set to 0 since calculated index will always be greater than 0
    	double max;
    	
    	//min is set to 100 
    	double min;
    	
    	//variable names for max/min of city
    	string mincity, maxcity;
    	
    	//declare input/output file names
    	ifstream inFile;
    	ofstream outputFile;
    	
    	//open input file				
    	inFile.open("costIndex.txt");
    	
    	//open output file
    	outputFile.open("index.txt");
    	
    	//open file; if fails exit program
    	if(inFile.fail())
    	{
    		cout << "File does not exist" << endl;
    		exit(100);
    	}
    	
    	cout << setprecision(1) << fixed;
    	
    	while (!inFile.eof())
    	{
    		//read whole line containing city location
    		getline(inFile, city);
    		
    		//input values of cost index into separate variables
    		inFile >> groceries >> housing >> utilities >> transportation >> health >> misc;
    		
    		//calculate the index cost for each city using computations function
    		index = computations(groceries, housing, utilities, transportation, health, misc);
    		
    		//pause after every calculation
    		string tempstr; getline(inFile, tempstr);
    		
    		//output result of city and calculated index to the output file
    		outputFile << left << setw(40) << city << setprecision(1) << fixed << right << setw(10) << index << endl;
    		
    		if (flag = 0)
    		max = index;
    		min = index;
    		{
    		
    		//calculate max index
    		if (index > max)
    		{
    			max = index;
    			maxcity = city;
    		}
    		
    		//calculate min index
    		else if (index <= min)
    		{
    			min = index;
    			mincity = city;
    		}
    		
    		flag = 1;
    		}
    	}
    	//output min and max index into the output file along with their city
    	outputFile << left << setw(40) << maxcity << right << setw(10) << max << endl; 
    	outputFile << left << setw(40) << mincity << right << setw(10) << min << endl; 
    
    
    	//close file - done
    	outputFile.close();
    	
    	//output min and max index 
    	cout << maxcity << endl;
    	cout << max << endl;
    	cout << mincity << endl;
    	cout << min << endl;
    	cout << "\nWon Kim\n" << "teddykim09@gmail.com\n" << "Lab #6";
    }
    
    
    double computations(double groc, double house, double util, double transp, double health, double misc)
    {
    	/* Pre: groc = groceries cost
    			house - housing cost
    			util = utilities cost
    			transp = transportation cost
    			health = health cost
    			misc = miscellaneous goods & services cost
    		Post: calculation of composite index
    		Purpose: Calculate the composite index from the various cost for each name and state of a city
    	*/
    	double total;
    	//calculate total = index 
    	total = 0.13 * groc + 0.29 * house + 0.10 * util + 0.12 * transp + 0.12 * health + 0.24 * misc;
    	return total;
    }
    So my professor recommended me to use flags to calculate the max and min. I initialized flag = 0 which is false. It runs the if statements initializing max/min to the value of the first index value, then comparing it to the previous when once the while loop cycles through. The max value I get is what I expect it to be but the min value is not. In fact the min value returns basically the last two lines of the input file I am grabbing the data from. I'm not sure why my minimum statement here is not working correctly. Anyone got any ideas?

  12. #12
    Registered User
    Join Date
    May 2019
    Posts
    209
    Ditch the else before testing for min
    Last edited by Niccolo; 06-16-2019 at 07:28 PM.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,231
    Don't name flags "flag": it only tells the reader that it is a flag without saying what the flag is for and what does a true or false value for the flag mean. Name it something like "first_iteration_flag", and since flags are boolean in nature, the type should be bool.

    Note that if (flag = 0) and if (flag == 0) are rather different.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    May 2019
    Posts
    23
    Quote Originally Posted by Niccolo View Post
    Ditch the else before testing for min
    That doesn't do anything as I still get the same result

  15. #15
    Registered User
    Join Date
    May 2019
    Posts
    23
    Quote Originally Posted by laserlight View Post
    Don't name flags "flag": it only tells the reader that it is a flag without saying what the flag is for and what does a true or false value for the flag mean. Name it something like "first_iteration_flag", and since flags are boolean in nature, the type should be bool.

    Note that if (flag = 0) and if (flag == 0) are rather different.
    Thanks for catching that. Should've been using the equality operator. And I will rename flag in my final iteration of program as soon as I get it to work, just a name holder for now. Program still isn't working as intended as Min is calculating the same result. I don't understand because in my head this code should work and i see no reason for it not to

    Set a flag to zero outside the loop. Within the loop after calculating first cost index, if flag is zero initialize maximum and minimum to this first value and change the flag to something like 1.
    This is the suggestion my teacher provided; however it just doesn't seem to work for me

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-14-2015, 10:05 PM
  2. Renaming a file with a variable as the input name
    By cherryduck in forum C Programming
    Replies: 6
    Last Post: 11-08-2009, 01:00 PM
  3. Finding values in input file
    By ToxicLove in forum C Programming
    Replies: 3
    Last Post: 05-02-2004, 06:19 PM
  4. Replies: 3
    Last Post: 06-25-2003, 04:29 PM
  5. finding the type of a input variable
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2002, 08:40 AM

Tags for this Thread