运用C++MFC编程,已知文件路径,该文件下有多份CSV测试文件,CSV测试文件内容格式一致,都是六列多行,每一行代表一个测试项,也就是说所有CSV文件同一行都是相同的测试项;从列来看,第二列是测试名字,第三列是测试下限,第四列是测试值,第五列是测试上限;从行来看,每个CSV文件相同行测试名字,测试上下限都一样,仅有测试值不同,而不同行测试名字及内容测试值都不一样。现在需要通过按键遍历该文件夹下的所有CSV文件,然后把不同文件夹下的相同测试项的测试值取出来求平均值,最后在列表控件上显示出每个测试项的名字,测试下限,测试平均值,测试上限。如何通过MFC代码实现
时间: 2023-07-04 10:06:37 浏览: 112
C++ 人事管理系统(实验)
实现步骤如下:
1. 创建一个 MFC 对话框应用程序,添加一个按钮和一个列表框控件。
2. 在按钮的响应函数中,使用 CFileDialog 类选择指定文件夹下的所有 CSV 文件,并将它们的文件名存储在一个字符串数组中。
3. 遍历这些 CSV 文件,对于每个文件,读取其中的测试值并计算平均值,并把每个测试项的名字、测试下限、测试平均值和测试上限存储在一个结构体数组中。
4. 把结构体数组中的数据显示在列表框控件中。
下面是具体的代码实现:
首先,在 CTestItem 类中定义一个用于存储测试项数据的结构体:
```C++
struct TestItemData
{
CString name; // 测试项名字
double lower; // 测试项下限
double upper; // 测试项上限
double avg; // 测试项平均值
};
```
然后,在对话框类的头文件中声明变量:
```C++
class CMyDlg : public CDialogEx
{
public:
CStringArray m_fileNames; // 选择的文件名数组
std::vector<TestItemData> m_data; // 测试项数据数组
// ...
};
```
接着,在按钮的响应函数中使用 CFileDialog 类选择指定文件夹下的所有 CSV 文件,并将它们的文件名存储在 m_fileNames 数组中:
```C++
void CMyDlg::OnBnClickedButton1()
{
// 选择文件夹
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("CSV Files (*.csv)|*.csv|All Files (*.*)|*.*||"), this);
dlg.GetOFN().lpstrTitle = _T("Select Folder");
dlg.GetOFN().Flags |= OFN_ALLOWMULTISELECT | OFN_EXPLORER;
if (dlg.DoModal() == IDOK)
{
POSITION pos = dlg.GetStartPosition();
CString fileName;
while (pos != NULL)
{
fileName = dlg.GetNextPathName(pos);
m_fileNames.Add(fileName);
}
}
}
```
接下来,遍历这些 CSV 文件,对于每个文件,读取其中的测试值并计算平均值,并把每个测试项的名字、测试下限、测试平均值和测试上限存储在 m_data 数组中:
```C++
void CMyDlg::OnBnClickedButton2()
{
// 清空列表框和数据数组
m_data.clear();
m_list.ResetContent();
// 遍历文件名数组
for (int i = 0; i < m_fileNames.GetCount(); i++)
{
CString fileName = m_fileNames[i];
std::ifstream file(fileName);
if (!file.is_open())
{
AfxMessageBox(_T("Failed to open file: ") + fileName);
continue;
}
// 读取 CSV 文件
std::string line;
std::getline(file, line); // 忽略第一行标题行
while (std::getline(file, line))
{
std::stringstream ss(line);
std::string field;
int col = 1;
CString name;
double lower = 0.0;
double upper = 0.0;
double sum = 0.0;
int count = 0;
while (std::getline(ss, field, ','))
{
if (col == 2) // 测试项名字
{
name = CString(field.c_str());
}
else if (col == 3) // 测试项下限
{
lower = std::stod(field);
}
else if (col == 4) // 测试项值
{
double value = std::stod(field);
sum += value;
count++;
}
else if (col == 5) // 测试项上限
{
upper = std::stod(field);
}
col++;
}
if (count > 0)
{
double avg = sum / count;
TestItemData data = { name, lower, upper, avg };
m_data.push_back(data);
}
}
file.close();
}
// 显示数据到列表框
for (const auto& data : m_data)
{
CString str;
str.Format(_T("%s\t%.2f\t%.2f\t%.2f"), data.name, data.lower, data.avg, data.upper);
m_list.AddString(str);
}
}
```
最后,在 OnInitDialog() 函数中初始化列表框控件:
```C++
BOOL CMyDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_list.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 100);
m_list.InsertColumn(1, _T("Lower"), LVCFMT_LEFT, 80);
m_list.InsertColumn(2, _T("Average"), LVCFMT_LEFT, 80);
m_list.InsertColumn(3, _T("Upper"), LVCFMT_LEFT, 80);
return TRUE;
}
```
阅读全文