C++ 从链表的.csv文件中读取输入
我对从文件中读取输入的知识一无所知,所以我不知道我错在哪里 这几乎就是代码:C++ 从链表的.csv文件中读取输入,c++,C++,我对从文件中读取输入的知识一无所知,所以我不知道我错在哪里 这几乎就是代码: Reservation* res = new Reservation(); ifstream fin("data.csv"); while(!fin.eof()) { fin >> res->ID; fin.get(); fin.getline
Reservation* res = new Reservation();
ifstream fin("data.csv");
while(!fin.eof()) {
fin >> res->ID;
fin.get();
fin.getline >> res->name;
fin.getline >> res->phone;
fin >> res->gridironID;
fin.get();
fin.getline >> res->hireDate;
fin.getline >> res->resDate;
fin.getline >> res->startTime;
fin.getline >> res->endTime;
fin >> res->isPay;
fin.get();
res->nextReservation = reservationHeader;
reservationHeader = res;
}
fin.close();
}
矿山结构:
struct Reservation
{
int ID;
char name[MAX_NAME_LENGTH];
char phone[MAX_PHONE_LENGTH];
int gridironID;
char hireDate[MAX_DATE_LENGTH];
char resDate[MAX_DATE_LENGTH];
char startTime[MAX_TIME_LENGTH];
char endTime[MAX_TIME_LENGTH];
bool isPay;
Reservation *nextReservation;
};
这是data.csv文件的一个示例:
100001,khang,01283478233,1,1,1,1,1,1
100002,Christina,01283478233,1,1,1,1,1,1
100003,GuanYung,01283478233,1,1,1,1,1,1
100004,kevin,01283478233,1,1,1,1,1,1
100005,minh,01283478233,1,1,1,1,1,1
我经常遇到的错误是:
Error 10 error C2297: '>>' : illegal, right operand has type 'char [12]'
Error 13 error C2297: '>>' : illegal, right operand has type 'char [12]'
Error 5 error C2297: '>>' : illegal, right operand has type 'char [15]'
//....(this pretty much the same for the other lines)
Error 1 error C3867: 'std::basic_istream<char,std::char_traits<char>>::getline': function call missing argument list; use '&std::basic_istream<char,std::char_traits<char>>::getline' to create a pointer to member
//...
错误10错误C2297:“>>”:非法,右操作数的类型为“char[12]”
错误13错误C2297:“>>”:非法,右操作数的类型为“char[12]”
错误5错误C2297:“>>”:非法,右操作数的类型为“char[15]”
//..(其他线路也差不多)
错误1错误C3867:'std::basic_istream::getline':函数调用缺少参数列表;使用“&std::basic\u istream::getline”创建指向成员的指针
//...
请以任何可能的方式帮助我:(您正在尝试的操作有两个直接的问题: 1.
std::istream>
不知道如何将数据推入C型数组。
2.std::istream
不知道,
是有效的分隔符
基本上是不走运的(1)。你可以切换到使用C++ <代码> STD::String < /Cult> s,而不是C风格的字符串,或者使用除<代码> >代码>之外的其他东西来读取数据。当然,在C结构中保留C风格字符串是有充分理由的,但是值得考虑的是其他选项。 让我们暂时使用C样式字符串。这是一个有用的函数:
fin.getline(res->name, MAX_NAME_LENGTH, ',');
这将从流中最多提取MAX\u NAME\u LENGTH-1个
字符(或者提取字符,直到找到逗号为止,以先到者为准)。这些字符将被放入字符数组中,然后该数组将以null结尾(因此它为什么不提取MAX\u NAME\u LENGTH
字符)。如果找到逗号,它将从流中删除,但不会添加到字符串中
现在,我注意到您在代码中检查的唯一条件是eof()
。这很好,但还不够。您还应该检查fin.fail()
。如果格式化函数未能提取要求它们提取的类型,或者getline
达到其缓冲区大小的末尾而没有看到分隔符,则将设置此项。设置failbit
后,其他读取将不会成功。您应该处理此错误情况,可能会引发错误,也可能会清除它并试图正常读取下一条记录,希望只有一条记录被破坏
那么分隔符呢
默认情况下,std::istream
要求字段以空格分隔。这就是为什么如果使用逗号分隔的值,大多数人最终会使用getline
提取每个字段
事实证明,流处理文本的方式非常灵活。我从这里的文档中选取了这个示例:
很简单,不是吗?换行符仍然被认为是字段分隔符,所以一切都应该“正常工作”
注意:你的代码和我的代码都不支持“真实”CSV,比如引用字符串。如果你需要那种功能,考虑找一个可以为你做的类或库。“CSV”“正确”比你想象的要复杂。“/p>因为你的编译器试图说:你在C++编程,摆脱C东西。”替换
字符名[大小]代码>带有字符串名称代码>。当你解决这个问题时…你会发现你不能使用getline()
,因为你的字段不是每行一个…用std::string
而不是char
s数组来表示你的字符串。你可能是指fin.getline(res->name)代码>和std::字符串名称代码>。同样相关的:谢谢你的指导,先生,但是字符类型是我作业中确定的一部分,所以我认为这里的解决方案是尝试通过某种可能的方式将这些字符转换成一个字符串,而不改变它在我的结构中的类型。所以我找到了这样一个简单的方法:string name=string(res->name)。你认为这样行吗?我完成fin任务后是否需要将其转换回char?您可以使用类似于std::strncpy(res->name,namestring.c_str(),MAX_name_LENGTH)的东西
将数据从std::string
移到char[]
中,但请确保先仔细阅读。
// This ctype facet classifies commas and endlines as whitespace
struct csv_whitespace : std::ctype<char> {
static const mask* make_table()
{
// make a copy of the "C" locale table
static std::vector<mask> v(classic_table(), classic_table() + table_size);
v[','] |= space; // comma will be classified as whitespace
v[' '] &= ~space; // space will not be classified as whitespace
return &v[0];
}
csv_whitespace(std::size_t refs = 0) : ctype(make_table(), false, refs) {}
};
// some function elsewhere in your code
stream.imbue(std::locale(stream.getloc(), new csv_whitespace()));
struct Reservation
{
int ID;
std::string name;
std::string phone;
int gridironID;
std::string hireDate;
std::string resDate;
std::string startTime;
std::string endTime;
bool isPay;
Reservation *nextReservation;
};
// reading from your imbued stream elsewhere:
while(!fin.eof()) {
fin >> res->ID >> res->name >> res->phone >> res->gridironID >>
res->hireDate >> res->resDate >> res->startTime >> res->endTime >>
res->isPay;
res->nextReservation = reservationHeader;
reservationHeader = res;
}
fin.close();