【问题标题】:How to count the number of a char each time you read it in?每次读入时如何计算一个字符的数量?
【发布时间】:2017-11-24 06:34:09
【问题描述】:

我是 C++ 班的学生。我需要帮助完成一项任务。

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

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

字母“M”和“F”代表性别,数字代表 他们的薪水。每次读到一个时,计算男性的数量,然后 将每个男性工资添加到累积的 totalMaleSalary 中。做同样的事情 女性。在循环结束时计算女性平均工资 和男性平均工资 - 显示您的结果并确定 2 个平均值中的哪​​一个更大。”

我将如何计算男性人数并添加每个工资?

这就是我所拥有的:

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

【问题讨论】:

  • 恐怕totalMaleSalary=salary+totalMaleSalary; 不行。您正在读取字符串。此外,M321232.34 中的M321232.34 之间也没有空格,可以将其输入到两个不同的变量中。
  • 如何添加正在读取的字符串?
  • @Dawn 你当前的代码有什么问题?
  • @apple apple 代码只是无限循环 cout。在课堂上,我得到了一个使用与地雷非常相似的代码的示例。当我运行它时,出现了同样的问题。我应该怎么做才能修复我的代码?

标签: c++ string file io floating-point


【解决方案1】:
  1. 不要假设文件已成功打开。使用if ( !is )...
  2. 不要使用eof()。提取成功时读取:while ( is &gt;&gt;...
  3. 读取整个文件后必须显示结果:cout &lt;&lt;... 必须在循环外。

你的固定程序:

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

【讨论】:

    【解决方案2】:

    我假设问题是使用该方法时字符没有与整数分开读取:fin&gt;&gt;gender&gt;&gt;salary;

    一个简单的解决方案是同时使用&lt;string&gt;&lt;sstream&gt; 类。

    代替:
    fin&gt;&gt;gender&gt;&gt;salary;

    有两个新变量:
    std::string input;std::stringstream stream;

    并使用此代码 sn-p 从文件中读取数据:

    鳍>>输入;

    性别 = 输入[0];

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

    字符串流基本上就像 iostream 或 filestream 一样,只是它不执行任何辅助功能,因此效率更高。

    它使您能够将数据放回流中,并在删除开头的字符后将其作为纯整数读出。

    【讨论】:

      【解决方案3】:

      您正在打开文件,但“do”只会读取一次数据,最后它会转到 while 并读取其余数据直到文件末尾,避免这样做。 “做” 1)逐行读取文件中的数据。 例如:(第一行)M321232.34 2)为“M”定义一个字符。 3)将读取的行存储在缓冲区中并在行中找到字符。 例如:char *buf = malloc(10+1) M321232.34
      4)一旦找到“M”或“F”,计算它并增加它的值。 例如:找到 countm++ 的“M”;或 "F" 找到 countf++; 5)如果找到“M”,则将除“M”之外的数据复制到另一个缓冲区中,并将其转换为整数并添加。 例如:找到 M321232.34 “M”,然后 msum=msum+34; 6)else "F" 找到将除"F" 之外的数据复制到另一个缓冲区中,并将其转换为整数并相加。 例如:找到 F321232.34 "F" 然后 fsum=fsum+34; 7)最后做平均......你的程序准备好了。谢谢

      【讨论】:

        【解决方案4】:

        这是我的方法:

        1. 使用 double 变量存储男性工资的总和,使用 int 变量存储读取的男性工资数。女性也一样。
        2. 逐行读取文件(查看我的example)。
        3. 对于每一行,检查第一个字母。如果是'M',则增加男性计数器,并将其工资添加到男性总工资中。女性也一样,当你遇到'F'这封信时。
        4. 计算男性工资的平均值,按计数器计算总和。女性也一样。
        5. 比较平均值并打印消息。

        完整代码示例:

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

        输出:

        男性的平均工资比女性高。


        附录:

        这一行:

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

        使用double stod (const string&amp; str, size_t* idx = 0); 将字符串转换为双精度。

        我们不能将"M321232.34" 作为参数传递,因为这会引发无效参数异常。我们需要获取子字符串,从第二个字符到最后一个字符(即仅数字)。

        因此,我们可以通过构造一个新字符串来构造原始字符串的子字符串,从它的第二个字符到最后一个字符,该新字符串将从原始字符串的开头 + 1 开始,并在结尾处结束原来的字符串,像这样:

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

        所以这将给出"321232.34",这是std::stod() 的一个很好的参数,允许函数成功返回参数字符串的双精度数。

        【讨论】:

        • @EricPostpischil 你是对的!你也应该投反对票。我的回答被解雇了!我更新了,现在怎么样了?
        猜你喜欢
        • 1970-01-01
        • 2014-04-17
        • 1970-01-01
        • 2022-10-15
        • 1970-01-01
        • 2015-12-07
        • 2017-02-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多