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

C++用getline读取CSV到数组后字符串转int值为0的问题排查

问题原因与解决方法

两个核心问题的根源

不管是年份转int返回0,还是匹配不到"USA",本质都是读取的字符串包含CSV自带的双引号:

  • 年份列实际读入的是"2019"而非2019,atoi遇到开头的双引号(非数字)直接返回0
  • 国家列读入的是"USA"而非USA,和纯字符串"USA"比较自然不相等

解决步骤

1. 写一个辅助函数去除字符串前后的双引号

#include <string>
using namespace std;

string stripQuotes(string s) {
    // 检查字符串首尾是否是双引号,是则截取中间内容
    if (s.length() >= 2 && s[0] == '"' && s[s.length()-1] == '"') {
        return s.substr(1, s.length() - 2);
    }
    return s;
}

2. 修改ReadFile函数,处理读入的字符串

在读取loc[x]和yr[x]之后,立即调用辅助函数去掉引号:

bool ReadFile(string loc[], string yr[], float rates[])
{   
    ifstream input{FILENAME.c_str()};
    if (!input)
    {
        return false;
    }

    string trash, temp;
    // 跳过表头
    getline(input, trash);
    
    for (int x{ 0 }; x < SIZE; ++x)
    {
        getline(input, loc[x], ',');
        loc[x] = stripQuotes(loc[x]); // 处理国家字符串
        
        getline(input, trash, ','); 
        getline(input, trash, ','); 
        getline(input, trash, ','); 
        getline(input, trash, ','); 
        
        getline(input, yr[x], ',');
        yr[x] = stripQuotes(yr[x]); // 处理年份字符串
        int year = atoi(yr[x].c_str()); // 现在能正确转成int了
        
        getline(input, temp, ',');
        // 处理空值情况(比如最后一列的 trailing comma)
        rates[x] = temp.empty() ? 0.0f : atof(temp.c_str());
        
        // 测试输出:现在内容都是不带引号的了
        cout << "国家:" << loc[x] << ",年份:" << year << ",生育率:" << rates[x] << endl;
    }
    return true;
}

3. 修复Analyze函数的小问题

  • 原代码遍历最高/最低生育率时从i=1开始,会漏掉第0个元素,改成从i=0开始
  • 匹配"USA"的逻辑现在可以正常工作,因为loc[x]已经是不带引号的字符串了

修改后的Analyze函数:

void Analyze(string loc[], string yr[], float rates[], FertilityResults& result)
{
    float tempArray[SIZE];
    for (int i{ 0 }; i < SIZE; ++i)
    {
        tempArray[i] = rates[i];
    }
    
    result.highestRate = 0;
    result.lowestRate = 20;
    result.highestRateIndex = 0;
    result.lowestRateIndex = 0;

    // 从i=0开始遍历,避免漏掉第一个元素
    for (int i{ 0 }; i < SIZE; ++i)
    {
        if (tempArray[i] >= result.highestRate)
        {
            result.highestRate = tempArray[i];
            result.highestRateIndex = i;
        }
        // 去掉else,否则会错过同时满足最高和最低的边界情况
        if (tempArray[i] > 0 && tempArray[i] < result.lowestRate)
        {
            result.lowestRate = tempArray[i];
            result.lowestRateIndex = i;
        }
    }
    
    // 现在能正常匹配USA了
    for (int i{ 0 }; i < SIZE; ++i)
    {
        if (loc[i] == "USA")
        {
            cout << "找到USA数据,索引:" << i << endl;
            result.usaIndex = i;
            // 如果有多个USA行,这里只会记录最后一个的索引,需要的话可以改成存数组或者第一个
        }
    }
}

额外注意事项

  • 确保SIZE常量的值和CSV文件的实际数据行数一致,避免数组越界
  • 如果CSV中有空值(比如最后一列的逗号后为空),要在转float时做判断,避免atof返回0(虽然atof处理空字符串也返回0,但可以根据业务逻辑调整)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:55:27