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

C++读取复杂CSV文件遇getline匹配错误,寻求解决

C++读取CSV文件到Struct向量的问题与修复

问题概述

用C++读取.csv文件并存储到struct的vector中,小型简单文件可运行,但无法适配复杂大文件。当前遇到编译错误:error: no matching function for call to 'getline(std::string&, char)',尝试直接将输入存入vector但因操作复杂未能成功。

当前代码

#include <string>
#include <fstream>
#include <iomanip>
#include <vector>
#include <sstream>
using namespace std;

struct Entry {
    string eb, ed, ee, ef, eh, ei, ej, el, ek, em, en, er, es, et, eu, ev, ew, ex, ey, ez, ea, eg, ec, eo, ep, eq;
    
        friend ostream& operator<<(ostream& os, const Entry e);
        friend istream& operator>>(istream& is, Entry& e);
};

Entry parse_Line(ifstream &source);
bool read_File(const char*);
void write_File(vector <Entry>& data);

//overloading operator << and >> to be able to print out the information needed.
ostream& operator<<(ostream& os, const Entry e)
{
    os << "d: " << e.ed << " e: " << e.ee << " f: " << e.ef << " h: " << e.ei << " m: " << e.em << "\n";
    return os;
}

istream& operator>>(istream& is, Entry& e){
    getline(e.ea, ',');
    getline(is >> ws, e.eb, ',');
    getline(is >> ws, e.ec, ',');
    getline(is >> ws, e.ed, ',');
    getline(is >> ws, e.ee, ',');
    getline(is >> ws, e.ef, ',');
    getline(is >> ws, e.eg, ',');
    getline(is >> ws, e.eh, ',');
    getline(is >> ws, e.ei, ',');
    getline(is >> ws, e.ej, ',');
    getline(is >> ws, e.ek, ',');
    getline(is >> ws, e.el, ',');
    getline(is >> ws, e.em, ',');
    getline(is >> ws, e.en, ',');
    getline(is >> ws, e.eo, ',');
    getline(is >> ws, e.ep, ',');
    getline(is >> ws, e.eq, ',');
    getline(is >> ws, e.er, ',');
    getline(is >> ws, e.es, ',');
    getline(is >> ws, e.et, ',');
    getline(is >> ws, e.eu, ',');
    getline(is >> ws, e.ev, ',');
    getline(is >> ws, e.ew, ',');
    getline(is >> ws, e.ex, ',');
    getline(is >> ws, e.ey, ',');
    
    return(is >> e.ez);
} 

Entry parse_Line(ifstream& source){
    string eb, ed, ee, ef, eh, ei, ej, el, ek, em, en, er, es, et, eu, ev, ew, ex, ey, ez, ea, eg, ec, eo, ep, eq;
    Entry tempEntry;
    
    //scan a line from the file
    source >> ea >> eb >> ec >> ed >> ef >> eg >> eh >> ei >> ej >> ek >> el >> em >> en >> eo >> ep >> eq >> er >> es >> et >> eu >> ev >> ew >> ex >> ey >> ez;
    
    /*while(getline(str, word, ','))
        row.push_back(word);
        content.push_back(row);*/
    
    
    //assign data to tempEntry
    tempEntry.ea = ea;
    tempEntry.eb = eb;
    tempEntry.ec = ec;  
    tempEntry.ed = ed;
    tempEntry.ee = ee;
    tempEntry.ef = ef;
    tempEntry.eg = eg;
    tempEntry.eh = eh;
    tempEntry.ei = ei;
    tempEntry.ej = ej;
    tempEntry.ek = ek;
    tempEntry.el = el;
    tempEntry.em = em;
    tempEntry.en = en;
    tempEntry.eo = eo;
    tempEntry.ep = ep;
    tempEntry.eq = eq;
    tempEntry.er = er;
    tempEntry.es = es;
    tempEntry.et = et;
    tempEntry.eu = eu;
    tempEntry.ev = ev;
    tempEntry.ew = ew;
    tempEntry.ex = ex;
    tempEntry.ey = ey;
    tempEntry.ez = ez;
    return tempEntry;
} 

bool read_File(const char* fileName, vector <Entry>& allData){
//take in file name and name of struct created to store data.
    string line;
    
    ifstream fileInput;
    fileInput.open(fileName, ios::in);
    
    if (fileInput.is_open()){
        // take each line, put it into the parse_Line function, then put it into the allData vector.
        for (Entry e; fileInput >> e; allData.push_back(move(e)));
            
        fileInput.close();
        
         
        write_File(allData);
        return true;
    } else {
        return false;
    }
    
}

void write_File(vector <Entry>& data){
    //use vector passed in and print it to console for now. will change to printing a new csv file
    for (int i=0; i<=data.size(); i++ ){
        cout << data[i] << " ";
    }
    
    return;
}

int main (int argc, char* argv[]) {
    //check for file
    if (argc < 2){
        return(cout << "No file name specified\n"),1;
    }
    //read in file name to a function using following:
    string str(argv[1]);
    vector <Entry> data;
    
    if (!read_File(argv[1], data)){
        return(cout << "That file name is invalid\n"), 2;
    }
    
    const char* nameStr = str.c_str();
    read_File(nameStr, data);
    

    return 0;
} 

输入文件示例

3902,string1,3,string two,string three,string 4,string five,230,string 6,string seven,string 8,string nine,stringten,string11,string12,string13,43,34,89,string 14,string 15,string 16,string 17,string eighteen,string nineteen,string twenty,string twenty one,string 22

92,b,324,c,d,e,f,g,h,i,j,k,l,m,n,43l,93403,392,r,s,t,u,v,w,x,y,z

问题分析与修复

1. 编译错误根源

getline(e.ea, ',')调用错误:std::getline的第一个参数必须是istream对象,不能直接传string。正确写法应为getline(is >> ws, e.ea, ',')。

2. CSV字段读取问题

  • parse_Line函数中用>>运算符读取会被空格截断,无法处理包含空格的CSV字段(如示例中的string two)。
  • operator>>中最后用is >> e.ez同样会被空格/换行截断,应改为getline(is >> ws, e.ez)(读取到行末)。

3. 其他逻辑错误

  • write_File中循环条件i<=data.size()会导致越界访问,应改为i < data.size()。
  • main函数中重复调用read_File,会导致数据被重复读取存入vector。
  • 需确保CSV的字段数量与Entry结构体的成员数量完全匹配,否则会出现读取错位。

修复后的代码

#include <string>
#include <fstream>
#include <iomanip>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;

struct Entry {
    string ea, eb, ec, ed, ee, ef, eg, eh, ei, ej, ek, el, em, en, eo, ep, eq, er, es, et, eu, ev, ew, ex, ey, ez;
    
    friend ostream& operator<<(ostream& os, const Entry& e);
    friend istream& operator>>(istream& is, Entry& e);
};

bool read_File(const char* fileName, vector<Entry>& allData);
void write_File(const vector<Entry>& data);

ostream& operator<<(ostream& os, const Entry& e)
{
    os << "d: " << e.ed << " e: " << e.ee << " f: " << e.ef << " h: " << e.ei << " m: " << e.em << "\n";
    return os;
}

istream& operator>>(istream& is, Entry& e){
    // 按顺序读取所有字段,处理带空格的内容
    getline(is >> ws, e.ea, ',');
    getline(is >> ws, e.eb, ',');
    getline(is >> ws, e.ec, ',');
    getline(is >> ws, e.ed, ',');
    getline(is >> ws, e.ee, ',');
    getline(is >> ws, e.ef, ',');
    getline(is >> ws, e.eg, ',');
    getline(is >> ws, e.eh, ',');
    getline(is >> ws, e.ei, ',');
    getline(is >> ws, e.ej, ',');
    getline(is >> ws, e.ek, ',');
    getline(is >> ws, e.el, ',');
    getline(is >> ws, e.em, ',');
    getline(is >> ws, e.en, ',');
    getline(is >> ws, e.eo, ',');
    getline(is >> ws, e.ep, ',');
    getline(is >> ws, e.eq, ',');
    getline(is >> ws, e.er, ',');
    getline(is >> ws, e.es, ',');
    getline(is >> ws, e.et, ',');
    getline(is >> ws, e.eu, ',');
    getline(is >> ws, e.ev, ',');
    getline(is >> ws, e.ew, ',');
    getline(is >> ws, e.ex, ',');
    getline(is >> ws, e.ey, ',');
    // 最后一个字段读取到行末
    getline(is >> ws, e.ez);
    
    return is;
} 

bool read_File(const char* fileName, vector<Entry>& allData){
    ifstream fileInput(fileName);
    if (!fileInput.is_open()){
        return false;
    }
    
    Entry e;
    // 逐行读取解析
    string line;
    while (getline(fileInput, line)) {
        istringstream iss(line);
        if (iss >> e) {
            allData.push_back(e);
        }
    }
    
    fileInput.close();
    write_File(allData);
    return true;
}

void write_File(const vector<Entry>& data){
    for (size_t i = 0; i < data.size(); ++i ){
        cout << data[i];
    }
}

int main (int argc, char* argv[]) {
    if (argc < 2){
        cout << "No file name specified\n";
        return 1;
    }
    
    vector<Entry> data;
    if (!read_File(argv[1], data)){
        cout << "That file name is invalid\n";
        return 2;
    }

    return 0;
} 

优化说明

  • 调整Entry成员顺序,与CSV字段顺序对应,避免读取错位。
  • 改用istringstream逐行解析CSV,确保每行数据独立处理,适配大文件。
  • 修复getline调用错误、循环越界、重复读取等问题。
  • 传递Entry对象时使用引用,减少拷贝开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:06:26