如何在C++中使用ostream&将文件读取的数组数据传入打印函数?
问题与解决方案
需求
- 从文本文件读取数据,存储到基于
struct的数组中 - 通过
ostream&打印数组内的数据 - 后续需整合
enum class的字符串转换逻辑
原始代码与文件格式
原始代码
const int maxRows =20; //3 columns across struct someThing{ string a; int b; int c; } void readFile (someThing arr[], int x) { //do stuff //open file... //loop } void printArray (ostream&, someThing thing){ //?? I am not sure what to here... //cout <<thing.a <<','<<thing.b <<','<<thing.c <<endl; for (int i = 0; i < maxRows; i++){ cout << thing[i]; }
文本文件格式
thing1 15.30 48 thing2 20.15 78 thing3 108.23 56
(共20行,每行包含字符串、浮点数、整数)
待整合的enum class代码
switch (thing.size){ case thingType:: S: "Small"; break; case thingType::M: "Medium"; break; case thingType::L: "Large"; break; }
已尝试的方法
- 使用
ostream& os后写os<<thing[i];,出现运算符重载和引用错误 - 搜索相关关键词、查阅cplusplus论坛、阅读C++书籍,但仍有困惑
- 暂未找到enum class的有效处理方法,先移除该部分
解决方案
1. 修正基础定义与函数参数
首先修正struct语法错误(末尾加;),调整printArray参数为数组+实际读取行数(而非单个对象),同时整合enum class到struct中:
#include <iostream> #include <fstream> #include <string> using namespace std; const int maxRows = 20; struct someThing{ string a; // 文件第二个字段是浮点数,保留小数改为double;若需存整数可做转整处理 double b; int c; // 整合enum class enum class thingType { S, M, L }; thingType size; };
2. 实现readFile函数
打开文件循环读取数据,记录实际读取的行数(避免硬编码maxRows):
// 返回实际读取的行数,传入数组和最大容量 int readFile(someThing arr[], int maxRows) { ifstream inFile("data.txt"); // 替换为你的文件路径 if (!inFile) { cerr << "无法打开文件" << endl; return 0; } int count = 0; // 读取直到文件结束或达到最大行数 while (count < maxRows && inFile >> arr[count].a >> arr[count].b >> arr[count].c) { // 可默认赋值enum,或从文件读取(若文件包含该字段) arr[count].size = someThing::thingType::M; count++; } inFile.close(); return count; }
3. 实现printArray与ostream重载
方式一:直接在函数内输出字段
void printArray(ostream& os, const someThing arr[], int rowCount) { for (int i = 0; i < rowCount; i++) { os << arr[i].a << ", " << arr[i].b << ", " << arr[i].c; // 处理enum class转字符串 switch (arr[i].size) { case someThing::thingType::S: os << ", Small"; break; case someThing::thingType::M: os << ", Medium"; break; case someThing::thingType::L: os << ", Large"; break; } os << endl; } }
方式二:重载ostream运算符(更符合C++风格)
先写enum转字符串的辅助函数,再重载<<:
string thingTypeToString(someThing::thingType type) { switch (type) { case someThing::thingType::S: return "Small"; case someThing::thingType::M: return "Medium"; case someThing::thingType::L: return "Large"; default: return "Unknown"; } } ostream& operator<<(ostream& os, const someThing& thing) { os << thing.a << ", " << thing.b << ", " << thing.c << ", " << thingTypeToString(thing.size); return os; } // 简化后的printArray void printArray(ostream& os, const someThing arr[], int rowCount) { for (int i = 0; i < rowCount; i++) { os << arr[i] << endl; } }
4. 主函数调用示例
int main() { someThing arr[maxRows]; int actualRows = readFile(arr, maxRows); // 打印到控制台 printArray(cout, arr, actualRows); // 打印到文件 ofstream outFile("output.txt"); if (outFile) { printArray(outFile, arr, actualRows); outFile.close(); } return 0; }
关键问题说明
- printArray参数错误:原代码传入单个
someThing对象,无法用数组下标访问,需改为数组+实际行数 - ostream使用错误:原代码直接用
cout,未使用传入的ostream&参数,导致无法灵活输出到控制台或文件 - 运算符重载问题:直接
cout << thing[i]报错是因为C++默认不支持自定义struct的输出,需重载ostream& operator<< - enum class处理:原switch语句未返回字符串,需封装为辅助函数返回对应文本描述
内容的提问来源于stack exchange,提问作者Ceola Eastwood
相关产品推荐
相关产品推荐

