1

I am a student in a c++ class. I need help with an assignment.

"Read from a text file called salaries.txt that contains the following format:

M321232.34
F43234.34
M23432.23
M191929.34

The letter 'M' and 'F' represents the gender and the number represents their salary. Count the number of Males each time you read one in, and add each of the male salaries to a cumulative totalMaleSalary. Do the same for the female. At the end of the loop compute the average female salary and average male salary - display your results and also determine which of the 2 averages is greater."

How would I count the numbers of males and add each of the salaries?

This is what I have:

int main(){

    int male=0, female=0;
    double salary,totalMaleSalary=0,totalFemaleSalary=0;
    char gender;

    ifstream fin;
    fin.open("salary.txt");
    do{
        fin>>gender>>salary;
        if(gender=='M'){
            male=male+1;
            totalMaleSalary=salary+totalMaleSalary;
        }
        if(gender=='F'){
            female=female+1;
            totalFemaleSalary=salary+totalFemaleSalary;
        }

        cout<<"Number of Males is "<<male<<endl;
        cout<<"Number of Females is "<<female<<endl;
        cout<<"Total Male Salary is "<<totalMaleSalary<<endl;
        cout<<"Total Female Salary is "<<totalFemaleSalary<<endl;
        cout<<"Average Male salary is "<<totalMaleSalary/male<<endl;
        cout<<"Average Female salary is "<<totalMaleSalary/female<<endl;

    }while(!fin.eof());


    fin.close();
    return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Dawn
  • 13
  • 3
  • I am afraid `totalMaleSalary=salary+totalMaleSalary;` won't work. You are reading character strings. Also there is no space between `M` and `321232.34` in `M321232.34` for it to be inputted in two different variables. – Aditi Rawat Nov 24 '17 at 06:41
  • How would I add the character strings being read? – Dawn Nov 24 '17 at 06:50
  • @Dawn what wrong with your current code? – apple apple Nov 24 '17 at 06:53
  • maybe [why-is-iostreameof-inside-a-loop-condition-considered-wrong](https://stackoverflow.com/q/5605125/5980430) – apple apple Nov 24 '17 at 06:58
  • @apple apple The code just loops the cout infinitely. In class I was given a example using code very similar to mines. When I ran it, the same problem occured. What should I proceed on doing to fix my code? – Dawn Nov 24 '17 at 07:07
  • @Dawn I am not exactly sure but you might look into `stoi`. – Aditi Rawat Nov 24 '17 at 07:07
  • @Dawn if it loop infinitely, your file would have wrong format. (so `istream` never reach eof) – apple apple Nov 24 '17 at 07:40

4 Answers4

0

I am assuming that the problem is that the characters are not being read separate from the integers when using the method: fin>>gender>>salary;

An easy solution is to use both the <string> and <sstream> classes.

Instead of:
fin>>gender>>salary;

Have two new variables:
std::string input; and std::stringstream stream;

and use this code snippet to read in the data from the file:

fin >> input;

gender = input[0];

for (int character{1}; character < input.length(); character++) { stream.put(input[character]); } stream >> salary;

String stream basically acts like iostream or filestream except it doesn't perform any side functions an it therefore more efficient.

It enables you to put your data back into a stream and read it out as purely an integer once the character at the beginning has been removed.

James Stow
  • 461
  • 4
  • 3
0

you are opening the file but "do" will read the data only once and at last it will go to while and read the rest of the data till the end of the file,avoid doing so. "DO" 1)Read the data from file line by line. Ex: (1st line) M321232.34 2)define a char for "M". 3)store the line read in a buffer and find the char in the line. Ex: char *buf = malloc(10+1) M321232.34
4)once "M" or "F" is found count it and increment its value. Ex : "M" is found countm++; or "F" is found countf++; 5)if "M" is found copy the data excluding "M" in another buffer and convert it into integer and add it. Ex: M321232.34 "M" is found then msum=msum+34; 6)else "F" is found copy the data excluding "F" in another buffer and convert it into integer and add it. Ex: F321232.34 "F" is found then fsum=fsum+34; 7)last do average..and you program is ready.thanks

0

Here is my approach:

  1. Use a double variable to store the sum of male salaries, and an int variable to store the number of male salaries read. Same for females.
  2. Read the file line by line (check my example).
  3. For every line, check the first letter. If it is 'M', then increment the male counter, and add its salary to the total male salaries. Same for females, when you encounter the letter 'F'.
  4. Compute average of male salaries, by diving sum by counter. Same for females.
  5. Compare averages and print message.

Full code example:

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <numeric>

int main(void) {

  std::ifstream infile("salaries.txt");
  std::string line;
  double male_salaries = 0.0;
  int males_count = 0;
  double female_salaries = 0.0;
  int females_count = 0;
  while (std::getline(infile, line)) {
    std::cout << line << std::endl;
    if(line[0] == 'M') {
        male_salaries += std::stod(std::string(line.begin() + 1, line.end()));
        males_count++;
    } else if(line[0] == 'F') {
        female_salaries += std::stod(std::string(line.begin() + 1, line.end()));
        females_count++;
    } else
        std::cout << "Something went wrong with: " << line << std::endl;
  }
  double m_sal_avg = male_salaries / males_count;
  double f_sal_avg = female_salaries / females_count;  

  if(m_sal_avg > f_sal_avg)
      std::cout << "Male salary average is greaten than the one of the females.\n";
  else if(m_sal_avg < f_sal_avg)
      std::cout << "Female salary average is greaten than the one of the males.\n";
  else
      std::cout << "Averages are equal.\n";

  return 0;
}

Output:

Male salary average is greaten than the one of the females.


Appendix:

This line:

std::stod(std::string(line.begin() + 1, line.end()));

uses double stod (const string& str, size_t* idx = 0); to convert a string to a double.

We cannot pass "M321232.34" as an argument, since this will throw an invalid argument exception. We need to take the substring, from second character to last (i.e. the number only).

For that reason, we can construct a substring of the original string, from its second character to last, by constructing a new string, which will start from the begin of the original string + 1, and will end at the end of the original string, like this:

std::string(line.begin() + 1, line.end())

So this will give "321232.34", which is a good argument for std::stod(), allowing the function to successfully return the double number of the argument string.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • @EricPostpischil you are right! You should have downvoted too. My answered sacked! I updated, how does it look like now? – gsamaras Nov 24 '17 at 16:05
0
  1. Don't assume the file was successfully opened. Use if ( !is )....
  2. Don't use eof(). Read while the extraction is successful: while ( is >>....
  3. The result must be displayed after the whole file is read: cout <<... must be outside loop.

Your fixed program:

#include <iostream>
#include <fstream>

using namespace std;

int main() 
{
  std::ifstream is( "salary.txt" );
  if ( !is )
    return -1; // failed to open

  int male = 0, female = 0;
  double salary, totalMaleSalary = 0, totalFemaleSalary = 0;
  char gender;

  while ( is >> gender >> salary )
  {
    if ( gender == 'M' )
    {
      male = male + 1;
      totalMaleSalary = salary + totalMaleSalary;
    }
    else if ( gender == 'F' )
    {
      female = female + 1;
      totalFemaleSalary = salary + totalFemaleSalary;
    }
    else
      return -2; // unknown
  };

  cout << "Number of Males is " << male << endl;
  cout << "Number of Females is " << female << endl;
  cout << "Total Male Salary is " << totalMaleSalary << endl;
  cout << "Total Female Salary is " << totalFemaleSalary << endl;
  cout << "Average Male salary is " << totalMaleSalary / male << endl;
  cout << "Average Female salary is " << totalMaleSalary / female << endl;

  return 0;
}
zdf
  • 4,382
  • 3
  • 18
  • 29