我的 ifstream 方法有什么问题?
What is wrong with my ifstream method?
在我的 class 我有这个 ifstream 方法
我需要它来读取文件并将信息写入我已经创建的对象
代码有问题
首先,a.engiene 值在值 - “gasoline”
之前插入 space
并且当给第二个对象和第三个对象赋值时,该方法没有为每个属性赋值正确。
friend ifstream& operator>>(ifstream& in, Auto &a)
{
char temp[31];
temp[0] = '[=10=]';
in.getline(temp, 30, ':');
if (temp[0])
{
in.getline(temp, 30, ':');
delete[]a.engine;
a.engine = new char[strlen(temp) + 1];
strcpy(a.engine, temp);
in.getline(temp, 30, ':');
a.max_speed = atoi(temp);
in.getline(temp, 30, ':');
a.engine_cc = atoi(temp);
in.getline(temp, 30, ':');
a.avg_consumption_urban = atoi(temp);
in.getline(temp, 30, ':');
a.avg_speed_urban = atoi(temp);
in.getline(temp, 30, ':');
a.avg_consumption = atoi(temp);
in.getline(temp, 30, ':');
a.avg_speed = atoi(temp);
return in;
}
else return in;
这是我在 main 中调用方法的方式:
ifstream f1("autoc.txt", ios_base::in);
f1 >> auto1 >> auto2 >> auto3;
这是文件数据:
auto1
engine: gasoline
max_speed: 250
engine_cc: 1980
avg_consumption_urban: 11
avg_speed_urban: 50
avg_consumption: 8
avg_speed: 100
auto2
engine: diesel
max_speed: 230
engine_cc: 1600
avg_consumption_urban: 9
avg_speed_urban: 50
avg_consumption: 6
avg_speed: 80
auto3
engine: hybrid
max_speed: 190
engine_cc: 1450
avg_consumption_urban: 7
avg_speed_urban: 50
avg_consumption: 4
avg_speed: 90
这是输出 window:
http://imgur.com/tHe49se
这与我的其他问题不重复。
我有这个几乎可以工作的代码。我需要让它为每个对象的属性分配正确的值。
in.getline(temp, 30, ':');
读取到 :
,即 属性 个名称。您还想提取之后的值,因此您需要添加
in.getline(temp, 30);
每个
之后
in.getline(temp, 30, ':');
但请记住,您的程序完全忽略了 属性 名称,而只是按值的顺序进行。我希望这能一劳永逸地解决你的问题。
我不敢添加一个更简洁的版本(你可能会再次询问),所以我只是提一下(就像我在你原来的问题的答案中所做的那样)。这是关于使用 std::string temp;
和 std::getline
而不是 std::istream::getline
.
我相信您可以将大部分解析委托给 STL 本身。你的 "autos" 的格式似乎是固定的并且有一个固定的顺序,这大大简化了解析的方法(你是否坚持使用 "char [31]" 不清楚,但如果你不是,你显然会使用 std::string 会更好,因为我添加到 Auto 结构的 "name" 字段就是这种情况)
工作示例:
#include <fstream>
#include <locale>
#include <iostream>
#include <string>
struct SeparatorReader: std::ctype<char>
{
template<typename T>
SeparatorReader(T &&seps):
std::ctype<char>(get_table(seps), true) {}
template<typename T>
std::ctype_base::mask const *get_table(T &&seps) {
auto rc = new std::ctype_base::mask[std::ctype<char>::table_size]();
for(auto &sep: seps)
rc[static_cast<unsigned char>(sep)] = std::ctype_base::space;
return &rc[0];
}
};
struct Auto
{
std::string name;
char engine[31];
int max_speed;
int engine_cc;
int avg_consumption_urban;
int avg_speed_urban;
int avg_consumption;
int avg_speed;
Auto(const std::string &name) : name(name) {}
friend std::istream &operator >>(std::istream &is, Auto &a);
friend std::ostream &operator <<(std::ostream &os, const Auto &a);
};
std::istream &operator >>(std::istream &is, Auto &a)
{
char tmp[31] = "";
is >> tmp; is >> a.engine; // skip field name, read value
is >> tmp; is >> a.max_speed;
is >> tmp; is >> a.engine_cc;
is >> tmp; is >> a.avg_consumption_urban;
is >> tmp; is >> a.avg_speed_urban;
is >> tmp; is >> a.avg_consumption;
is >> tmp; is >> a.avg_speed;
return is;
}
std::ostream &operator <<(std::ostream &os, const Auto &a)
{
os << a.name << std::endl;
os << "engine: " << a.engine << std::endl;
os << "max_speed: " << a.max_speed << std::endl;
os << "engine_cc: " << a.engine_cc << std::endl;
os << "avg_consumption_urban: " << a.avg_consumption_urban << std::endl;
os << "avg_speed_urban: " << a.avg_speed_urban << std::endl;
os << "avg_consumption: " << a.avg_consumption << std::endl;
os << "avg_speed: " << a.avg_speed << std::endl;
return os;
}
int
main(int argc, char *argv[])
{
std::ifstream stream(argv[1]);
stream.imbue(std::locale(stream.getloc(), new SeparatorReader(" :\n")));
std::string name;
while(stream >> name) {
Auto a(name);
stream >> a;
std::cout << "------------------------------" << std::endl;
std::cout << a;
}
}
如果我们将样本文件与您的样本输入一起传递...输出为:
------------------------------
auto1
engine: gasoline
max_speed: 250
engine_cc: 1980
avg_consumption_urban: 11
avg_speed_urban: 50
avg_consumption: 8
avg_speed: 100
------------------------------
auto2
engine: diesel
max_speed: 230
engine_cc: 1600
avg_consumption_urban: 9
avg_speed_urban: 50
avg_consumption: 6
avg_speed: 80
------------------------------
auto3
engine: hybrid
max_speed: 190
engine_cc: 1450
avg_consumption_urban: 7
avg_speed_urban: 50
avg_consumption: 4
avg_speed: 90
在我的 class 我有这个 ifstream 方法 我需要它来读取文件并将信息写入我已经创建的对象 代码有问题 首先,a.engiene 值在值 - “gasoline”
之前插入 space并且当给第二个对象和第三个对象赋值时,该方法没有为每个属性赋值正确。
friend ifstream& operator>>(ifstream& in, Auto &a)
{
char temp[31];
temp[0] = '[=10=]';
in.getline(temp, 30, ':');
if (temp[0])
{
in.getline(temp, 30, ':');
delete[]a.engine;
a.engine = new char[strlen(temp) + 1];
strcpy(a.engine, temp);
in.getline(temp, 30, ':');
a.max_speed = atoi(temp);
in.getline(temp, 30, ':');
a.engine_cc = atoi(temp);
in.getline(temp, 30, ':');
a.avg_consumption_urban = atoi(temp);
in.getline(temp, 30, ':');
a.avg_speed_urban = atoi(temp);
in.getline(temp, 30, ':');
a.avg_consumption = atoi(temp);
in.getline(temp, 30, ':');
a.avg_speed = atoi(temp);
return in;
}
else return in;
这是我在 main 中调用方法的方式:
ifstream f1("autoc.txt", ios_base::in);
f1 >> auto1 >> auto2 >> auto3;
这是文件数据:
auto1
engine: gasoline
max_speed: 250
engine_cc: 1980
avg_consumption_urban: 11
avg_speed_urban: 50
avg_consumption: 8
avg_speed: 100
auto2
engine: diesel
max_speed: 230
engine_cc: 1600
avg_consumption_urban: 9
avg_speed_urban: 50
avg_consumption: 6
avg_speed: 80
auto3
engine: hybrid
max_speed: 190
engine_cc: 1450
avg_consumption_urban: 7
avg_speed_urban: 50
avg_consumption: 4
avg_speed: 90
这是输出 window: http://imgur.com/tHe49se
这与我的其他问题不重复。 我有这个几乎可以工作的代码。我需要让它为每个对象的属性分配正确的值。
in.getline(temp, 30, ':');
读取到 :
,即 属性 个名称。您还想提取之后的值,因此您需要添加
in.getline(temp, 30);
每个
之后in.getline(temp, 30, ':');
但请记住,您的程序完全忽略了 属性 名称,而只是按值的顺序进行。我希望这能一劳永逸地解决你的问题。
我不敢添加一个更简洁的版本(你可能会再次询问),所以我只是提一下(就像我在你原来的问题的答案中所做的那样)。这是关于使用 std::string temp;
和 std::getline
而不是 std::istream::getline
.
我相信您可以将大部分解析委托给 STL 本身。你的 "autos" 的格式似乎是固定的并且有一个固定的顺序,这大大简化了解析的方法(你是否坚持使用 "char [31]" 不清楚,但如果你不是,你显然会使用 std::string 会更好,因为我添加到 Auto 结构的 "name" 字段就是这种情况)
工作示例:
#include <fstream>
#include <locale>
#include <iostream>
#include <string>
struct SeparatorReader: std::ctype<char>
{
template<typename T>
SeparatorReader(T &&seps):
std::ctype<char>(get_table(seps), true) {}
template<typename T>
std::ctype_base::mask const *get_table(T &&seps) {
auto rc = new std::ctype_base::mask[std::ctype<char>::table_size]();
for(auto &sep: seps)
rc[static_cast<unsigned char>(sep)] = std::ctype_base::space;
return &rc[0];
}
};
struct Auto
{
std::string name;
char engine[31];
int max_speed;
int engine_cc;
int avg_consumption_urban;
int avg_speed_urban;
int avg_consumption;
int avg_speed;
Auto(const std::string &name) : name(name) {}
friend std::istream &operator >>(std::istream &is, Auto &a);
friend std::ostream &operator <<(std::ostream &os, const Auto &a);
};
std::istream &operator >>(std::istream &is, Auto &a)
{
char tmp[31] = "";
is >> tmp; is >> a.engine; // skip field name, read value
is >> tmp; is >> a.max_speed;
is >> tmp; is >> a.engine_cc;
is >> tmp; is >> a.avg_consumption_urban;
is >> tmp; is >> a.avg_speed_urban;
is >> tmp; is >> a.avg_consumption;
is >> tmp; is >> a.avg_speed;
return is;
}
std::ostream &operator <<(std::ostream &os, const Auto &a)
{
os << a.name << std::endl;
os << "engine: " << a.engine << std::endl;
os << "max_speed: " << a.max_speed << std::endl;
os << "engine_cc: " << a.engine_cc << std::endl;
os << "avg_consumption_urban: " << a.avg_consumption_urban << std::endl;
os << "avg_speed_urban: " << a.avg_speed_urban << std::endl;
os << "avg_consumption: " << a.avg_consumption << std::endl;
os << "avg_speed: " << a.avg_speed << std::endl;
return os;
}
int
main(int argc, char *argv[])
{
std::ifstream stream(argv[1]);
stream.imbue(std::locale(stream.getloc(), new SeparatorReader(" :\n")));
std::string name;
while(stream >> name) {
Auto a(name);
stream >> a;
std::cout << "------------------------------" << std::endl;
std::cout << a;
}
}
如果我们将样本文件与您的样本输入一起传递...输出为:
------------------------------
auto1
engine: gasoline
max_speed: 250
engine_cc: 1980
avg_consumption_urban: 11
avg_speed_urban: 50
avg_consumption: 8
avg_speed: 100
------------------------------
auto2
engine: diesel
max_speed: 230
engine_cc: 1600
avg_consumption_urban: 9
avg_speed_urban: 50
avg_consumption: 6
avg_speed: 80
------------------------------
auto3
engine: hybrid
max_speed: 190
engine_cc: 1450
avg_consumption_urban: 7
avg_speed_urban: 50
avg_consumption: 4
avg_speed: 90