C++ - 无法将 CSV 解析为我的结构
C++ - Failing to parse CSV into my struct
我有一个格式如下的CSV:
date,fruit,quantity1,quantity2,quantity3
2016-07-14,banana,3,20,6
2016-07-14,banana,3,50,15
2016-07-14,banana,0,25,15
2016-07-14,banana,3,25,6
2016-07-14,apple,3,10,20.5
2016-07-14,apple,0,30,5
2016-07-14,apple,0,5,30
2016-07-14,peach,3,10,30.2
2016-07-14,peach,3,40,4
2016-07-14,peach,3,10,12
2016-07-14,peach,0,10,8
2016-07-14,peach,3,200,3
我想解析此文件并将其存储在结构中。 但是我遇到堆栈溢出错误。 它到底在哪里失败? 是因为结构中的数据类型冲突吗? 一些数据类型是浮点数,我正在尝试使用 getline 和临时字符串变量来存储信息。
以下是完整的代码:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
struct FruitInventory
{
string date;
string fruit;
float quantity1;
float quantity2;
float quantity3;
};
int main()
{
ifstream myfile;
myfile.open("fruit_inventory.csv", ios::in);
string line;
FruitInventory todaysFruitSupply[15000];
int i = 0;
int lineCount = 0;
while (myfile.good())
{
getline(myfile, line);
stringstream mystream(line);
string temp;
if (i > 0) //ignore header line
{
getline(mystream, todaysFruitSupply[i].date, ',');
getline(mystream, todaysFruitSupply[i].fruit, ',');
getline(mystream, temp, ',');
todaysFruitSupply[i].quantity1 = stof(temp);
getline(mystream, temp, ',');
todaysFruitSupply[i].quantity2 = stof(temp);
getline(mystream, temp, ',');
todaysFruitSupply[i].quantity3 = stof(temp);
}
i++;
lineCount++;
}
myfile.close();
system("pause");
return 0;
}
编辑:它在文件的最后一行中断,因为有一个换行符。 删除后,它现在完全执行。 我如何确保它将来可以正确处理这个问题?
这是一个要分配为局部变量的大型对象:
FruitInventory todaysFruitSupply[15000];
这显然是堆栈溢出的原因。正如上面的评论所说,您应该考虑一种动态数据结构,例如std::vector
,它将根据需要增长并自动管理其内存。
std::vector<FruitInventory> todaysFruitSupply;
它在文件的最后一行中断,因为有一个换行符。删除后,它现在完全执行。我如何确保它将来可以正确处理这个问题?
您应该检查当您阅读一行时它是否不为空:
while (myfile.good())
{
getline(myfile, line);
if (line.empty())
break;
或者更好的是,不要继续使用good()
而是测试输入操作的结果:
while (getline(myfile, line) && !line.empty())
{
整个事情看起来像:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
struct FruitInventory
{
string date;
string fruit;
float quantity1;
float quantity2;
float quantity3;
};
int main()
{
ifstream myfile;
myfile.open("fruit_inventory.csv", ios::in);
string line;
std::vector<FruitInventory> todaysFruitSupply;
int lineCount = 0;
getline(myfile, line); // ignore header line
FruitInventory inv;
while (getline(myfile, line) && !line.empty())
{
stringstream mystream(line);
string temp;
getline(mystream, inv.date, ',');
getline(mystream, inv.fruit, ',');
getline(mystream, temp, ',');
inv.quantity1 = stof(temp);
getline(mystream, temp, ',');
inv.quantity2 = stof(temp);
getline(mystream, temp, ',');
inv.quantity3 = stof(temp);
if (!mystream)
break; // something went wrong reading the line
todaysFruitSupply.push_back(inv);
lineCount++;
}
}
15K 微小结构的阵列不可能导致堆栈溢出。如果最初存在堆栈溢出,则从数据文件中删除一个空行都不会修复它。问题是不同的。
getline(myfile, line);
//After the above line in your code, you must add:
if ( myfile.eof() )
break;
这是因为如果文件处于良好状态,则在从中读取之前而不是在尝试从中读取之后,您将在循环中签入。或者,您可以一起加入 getline (..) && 文件对象运行状况检查:
while (getline(myfile, line) && myfile.good() )
这两个修复程序是等效的(对于这个问题,尽管从技术上讲它们是不同的),并且在当前的程序和数据中根本没有区别,但是随着程序员的成熟,他们会选择后者。如果此更改适合您,请在下面添加评论。
此外,您需要检查是否存在非空字符串,并使用不会导致异常的字符串分词器。您可以在学习 try/catch 时使用 IOException 处理程序。
相关文章:
- 为什么我的结构在包含字符串时崩溃?
- 为什么添加析构函数(甚至是空的)会破坏我的结构,该结构使用 ref 转发和折叠来保存 ref 或值的副本?
- C++ 编译器正在更改我的结构的对齐方式.我怎样才能防止这种情况
- 当我的结构中的任何变量发生更改时触发的事件的任何方法
- 如何在我的结构中使用库
- 如何从我的结构中打印人口最多的状态
- 编译器无法识别我的结构成员
- 我可以使用 std::sort 对 C 样式数组(在我的结构情况下)进行排序吗?
- 不确定在哪里定义并声明我的结构.(获得未申报的标识符)
- 将规则生产绑定到我的结构成员时出现编译错误
- 为什么我的结构中映射的构造函数不起作用
- 如何判断我的结构tm是否处于无效状态
- 使我的结构或类与std::round兼容
- 为什么我的结构不能有 boost::variant 类型的成员,但可以有 vector<boost::variant> 类型的成员?
- 我的结构的自定义排序
- 使用assign()是初始化我的c++结构向量的好方法吗?
- 使用我的结构作为返回类型的问题
- 在c++中调用time会改变我的结构体tm
- 尺寸给我的结构带来意想不到的结果
- 为什么我的结构体成员没有使用"{}"正确初始化?