You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中使用ostream&将文件读取的数组数据传入打印函数?

问题与解决方案

需求

  1. 从文本文件读取数据,存储到基于struct的数组中
  2. 通过ostream&打印数组内的数据
  3. 后续需整合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;
}

关键问题说明

  1. printArray参数错误:原代码传入单个someThing对象,无法用数组下标访问,需改为数组+实际行数
  2. ostream使用错误:原代码直接用cout,未使用传入的ostream&参数,导致无法灵活输出到控制台或文件
  3. 运算符重载问题:直接cout << thing[i]报错是因为C++默认不支持自定义struct的输出,需重载ostream& operator<<
  4. enum class处理:原switch语句未返回字符串,需封装为辅助函数返回对应文本描述

内容的提问来源于stack exchange,提问作者Ceola Eastwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:25:27