C++从文本文件计算销售人员平均销售额的动态适配问题
问题描述
使用C++从文本文件计算每位销售人员的平均销售额。当前代码可输出与样例一致的正确结果,但文本文件新增数据时需手动修改代码(比如固定大小的数组)才能运行,尝试多种方法均未完全满足需求。同时希望实现读取文件后自动累加所有同名人员的销售额。
当前代码
#include <iostream> #include <fstream> #include <iomanip> using namespace std; class Sales { public: int id; string name; int salesCount = 1; double salesAmount; double avgSalesAmount; }; void read() { int i = 0; Sales sale[4]; fstream read; read.open("Sales.txt"); while(!read.eof()) { read.ignore(); getline(read, sale[i].name); read >> sale[i].salesAmount; if (sale[i].name == sale[i-1].name) { sale[i-1].salesAmount = sale[i-1].salesAmount + sale[i].salesAmount; sale[i-1].salesCount++; sale[i].salesCount = 0; } i++; } read.close(); for (int x = 0; x < 4; x++) { if (sale[x].salesCount != 0) { sale[x].avgSalesAmount = sale[x].salesAmount / sale[x].salesCount; cout << sale[x].name << endl; cout << sale[x].salesCount << endl; cout << sale[x].avgSalesAmount << endl; } } } int main() { read(); return 0; }
样例文件Sales.txt内容
Matthew 123.45 Matthew 432.15 Brown 89.95 Cook 500.00
样例输出
Matthew 2 277.80 Brown 1 89.95 Cook 1 500.00
解决方案
核心问题在于原代码使用固定大小数组,无法适配新增数据;且仅能累加相邻的同名条目,无法处理非连续的同名数据。使用STL的std::map(或std::unordered_map)可完美解决这两个问题:通过姓名作为键自动聚合所有同名人员的销售额和销售次数,无需预设数组大小。
修改后的代码
#include <iostream> #include <fstream> #include <string> #include <map> #include <iomanip> #include <limits> using namespace std; void calculateSalesAverage() { // 键:销售人员姓名;值:pair(总销售额, 销售次数) map<string, pair<double, int>> salesData; ifstream inFile("Sales.txt"); if (!inFile.is_open()) { cerr << "无法打开文件!" << endl; return; } string name; double amount; // 安全的文件读取逻辑:直到读取失败为止 while (true) { // 读取姓名(处理前序换行符) if (!getline(inFile, name)) break; // 跳过空行 if (name.empty()) continue; // 读取销售额 if (!(inFile >> amount)) break; // 清理读取金额后残留的换行符,避免下一次getline读取空字符串 inFile.ignore(numeric_limits<streamsize>::max(), '\n'); // 自动累加同名数据:存在则更新,不存在则新增 salesData[name].first += amount; salesData[name].second += 1; } inFile.close(); // 格式化输出结果 cout << fixed << setprecision(2); for (const auto& entry : salesData) { const string& name = entry.first; double totalSales = entry.second.first; int saleCount = entry.second.second; double avgSales = totalSales / saleCount; cout << name << endl; cout << saleCount << endl; cout << avgSales << endl; } } int main() { calculateSalesAverage(); return 0; }
代码说明
- 容器选择:
std::map会自动按姓名排序,若不需要排序可改用std::unordered_map,查询效率更高。 - 文件读取优化:替换原代码中不安全的
while(!read.eof())逻辑,同时处理了换行符残留问题,避免读取错误。 - 自动聚合:无论同名数据是否连续,都能直接在
map中对应条目累加总销售额和次数。 - 扩展性:无需修改代码,即可处理任意数量的新增销售数据。
内容的提问来源于stack exchange,提问作者Aragorn
相关产品推荐
相关产品推荐

