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

C++中使用getline()处理跨行拆分的BLS文本数据问题

处理BLS文本数据中的跨行城市条目问题

问题场景与代码

读取BLS文本格式数据时,部分都会区名称过长导致对应城市的数据被拆分为两行,示例文件片段:

999 26380 Houma-Thibodaux, LA  42   42   0   0  0   0   94
288 26420 Houston-The Woodlands-Sugar Land,
  TX              4424    3046       4       0    1374      34     100
170 26580 Huntington-Ashland, WV-KY-OH  7   1   0   6   0    0     85

需要提取州信息后的7个整数,存入total, one, two, three, five, struc, per变量中。单行数据处理正常,但跨行的Houston数据无法正确读取——原本期望读取下一行的州和数字,实际getline(sin, line)持续读取空行。

当前使用的代码:

#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main() {
    ifstream BLS;
    vector <string> cities = {"Houston-The Woodlands-Sugar Land"};
    string city, state, total, one, two, three, five, struc, per, temp;
    BLS.open("trial.txt");
    if (BLS.is_open()) {
        string line;
        while(getline(BLS, line)) {
            istringstream sin(line);                 
            getline(sin, temp, ' ');
            getline(sin, temp, ' ');
            getline(sin, city, ','); 
            for (int i = 0; i < (int) cities.size(); i++) {
                if (city == cities[i]) {     
                    if (getline(sin, line) ) {
                        istringstream in(line);
                        in >> state >> total >> one >> two >> three >> five >> struc >> per;
                    }
                    else {
                        sin.ignore();
                        getline(sin, line);
                        istringstream in(line);
                        in >> state >> total >> one >> two >> three >> five >> struc >> per;
                    }
                    cout << " " << city << " " << state << " " << total << " " << five << endl;
                }
            }
        }
    }
}

问题分析

核心错误是混淆了**文件流BLS和字符串流sin**的作用:

  • sin是基于当前读取的单行内容创建的,只能处理该行剩余数据,无法读取文件的下一行。
  • 针对Houston的行,getline(sin, city, ',')已经读到行尾的逗号,sin内剩余内容为空,此时调用getline(sin, line)必然失败,后续操作自然无法获取下一行的州和数字。

修复方案

当检测到目标城市的当前行没有州信息时,直接从**文件流BLS**读取下一行,再解析州和数字。修正后的代码:

#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main() {
    ifstream BLS;
    vector<string> cities = {"Houston-The Woodlands-Sugar Land"};
    string city, state, total, one, two, three, five, struc, per, temp;
    BLS.open("trial.txt");
    if (BLS.is_open()) {
        string line;
        while (getline(BLS, line)) {
            istringstream sin(line);
            // 跳过前两个数字字段
            getline(sin, temp, ' ');
            getline(sin, temp, ' ');
            // 读取城市名称到逗号处
            getline(sin, city, ',');
            
            // 判断是否为目标城市
            bool is_target = false;
            for (const string& target_city : cities) {
                if (city == target_city) {
                    is_target = true;
                    break;
                }
            }
            if (!is_target) continue;
            
            // 跳过逗号后的空白字符,尝试读取州信息
            sin >> ws;
            if (!(sin >> state)) {
                // 当前行无州信息,读取文件下一行
                if (!getline(BLS, line)) break;
                istringstream next_line(line);
                next_line >> state >> total >> one >> two >> three >> five >> struc >> per;
            } else {
                // 当前行有州信息,直接读取后续数字
                sin >> total >> one >> two >> three >> five >> struc >> per;
            }
            
            cout << " " << city << " " << state << " " << total << " " << five << endl;
        }
    }
    return 0;
}

关键改进

  • 区分流的作用:读取下一行时直接操作文件流BLS,而非字符串流sin。
  • 空白处理:用sin >> ws跳过逗号后的所有空白,避免读取空内容。
  • 简化逻辑:提前判断是否为目标城市,减少嵌套层级,代码更清晰。
  • 异常防护:读取下一行时检查是否成功,避免文件提前结束引发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:35:22