从文件中,我如何从 C++ 中的某个点读取
From a file, how do I read from a certain point in C++
我想做的事情:
我需要在 void main() 中创建 3 个自动对象。
对于每个对象,我都有一个 txt 文件中的信息。
如何获取每个对象的信息(引擎、max_speed...等)。如何跳过读取 "engine" 以及如何在创建第二个对象时跳过整个 auto。谢谢!
txt 文件:(auto.txt)
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
到目前为止我所拥有的(我使用此代码使用 auto.txt 的更简单版本来读取和显示 - 请参阅下面我的 txt 文件的简单版本):
这是我在 Auto class
中的 ifstream 方法
friend ifstream& operator>>(ifstream& in, Auto &a)
{
delete[]a.engine;
a.engine = new char[10];
in >> a.engine;
in >> a.max_speed;
in >> a.engine_cc;
in >> a.avg_consumption_urban;
in >> a.avg_speed_urban;
in >> a.avg_consumption;
in >> a.avg_speed;
return in;
}
这就是我在 void main 中读取文件的方式
ifstream f("auto.txt", ios_base::in);
f >> auto1;
auto1.display();
f.close();
这是我阅读的文字。这是一个简化版本。
gasoline
250
1980
11
50
8
100
How do I skip reading "engine"?
如果您不想检查读取的内容,可以使用带有自定义分隔符的 std::ifstream::ignore
:
f.ignore(std::numeric_limits<std::streamsize>::max(), ':');
但是看到这些键被 :
或 space 与它们的值分隔开,您也可以使用 std::getline
读取到 :
或简单的 operator>>
读到 std::string
直到白色 space 包括 :
然后检查那个。
How do I skip a whole auto?
如果您的意思是将另一个 Auto
写入文件,您可以在追加模式下打开文件 - 使用 std::ios_base::out | std::ios_base::app
.
另一方面,如果你的意思是阅读信息,你可以通过重复调用(在循环中)来跳过看似恒定数量的行:
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
编辑:
要读取 :
之后的值,您可以使用:
operator>>
- 格式化提取然后 std::getline
或 std::istream::ignore
行的其余部分(以 \n
作为分隔符),所以下一个 std::getline
正确读取下一行
std::getline
用 \n
分隔符读取该行的其余部分,然后用 std::istringstream
解析并格式化提取。
在这两种情况下,您都可以知道值后面是否有多余的字符。
在文件格式中,没有定位到给定记录的有效方法。记录的大小可变,例如,一个引擎速度为 100(3 个字符),而另一个为 80(2 个字符)。
由于每个字段都在单独的行中,您可以阅读每个文本行,在文本的开头搜索 "engine"。
这个项目闻起来像是可以使用数据库。
如果必须逐行阅读,不妨逐条阅读。也就是说,让记录对象从文件中读取其成员。
如果在读取记录之前获得文件位置,则可以将信息存储到 std::map<unsigned int, Engine>
中并使用文件指针作为映射中的索引。
我说过这闻起来像它可以使用数据库吗?
另一个想法是读入所有记录并将它们推入std::vector
。创建一个 std::map<unsigned int, unsigned int>
以将矢量索引映射到文件位置。
仍然感觉你应该使用数据库。
通过将引擎记录放入向量中,您可以创建其他索引表(数据库可以为您创建索引表)。例如,std::map<string, unsigned int>
将引擎类型映射到矢量索引。
研究数据库理论,尤其是范式。当您使用数据库时,您将从这些知识中获益良多。
我想做的事情: 我需要在 void main() 中创建 3 个自动对象。 对于每个对象,我都有一个 txt 文件中的信息。
如何获取每个对象的信息(引擎、max_speed...等)。如何跳过读取 "engine" 以及如何在创建第二个对象时跳过整个 auto。谢谢!
txt 文件:(auto.txt)
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
到目前为止我所拥有的(我使用此代码使用 auto.txt 的更简单版本来读取和显示 - 请参阅下面我的 txt 文件的简单版本):
这是我在 Auto class
中的 ifstream 方法 friend ifstream& operator>>(ifstream& in, Auto &a)
{
delete[]a.engine;
a.engine = new char[10];
in >> a.engine;
in >> a.max_speed;
in >> a.engine_cc;
in >> a.avg_consumption_urban;
in >> a.avg_speed_urban;
in >> a.avg_consumption;
in >> a.avg_speed;
return in;
}
这就是我在 void main 中读取文件的方式
ifstream f("auto.txt", ios_base::in);
f >> auto1;
auto1.display();
f.close();
这是我阅读的文字。这是一个简化版本。
gasoline
250
1980
11
50
8
100
How do I skip reading "engine"?
如果您不想检查读取的内容,可以使用带有自定义分隔符的 std::ifstream::ignore
:
f.ignore(std::numeric_limits<std::streamsize>::max(), ':');
但是看到这些键被 :
或 space 与它们的值分隔开,您也可以使用 std::getline
读取到 :
或简单的 operator>>
读到 std::string
直到白色 space 包括 :
然后检查那个。
How do I skip a whole auto?
如果您的意思是将另一个 Auto
写入文件,您可以在追加模式下打开文件 - 使用 std::ios_base::out | std::ios_base::app
.
另一方面,如果你的意思是阅读信息,你可以通过重复调用(在循环中)来跳过看似恒定数量的行:
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
编辑:
要读取 :
之后的值,您可以使用:
operator>>
- 格式化提取然后std::getline
或std::istream::ignore
行的其余部分(以\n
作为分隔符),所以下一个std::getline
正确读取下一行std::getline
用\n
分隔符读取该行的其余部分,然后用std::istringstream
解析并格式化提取。
在这两种情况下,您都可以知道值后面是否有多余的字符。
在文件格式中,没有定位到给定记录的有效方法。记录的大小可变,例如,一个引擎速度为 100(3 个字符),而另一个为 80(2 个字符)。
由于每个字段都在单独的行中,您可以阅读每个文本行,在文本的开头搜索 "engine"。
这个项目闻起来像是可以使用数据库。
如果必须逐行阅读,不妨逐条阅读。也就是说,让记录对象从文件中读取其成员。
如果在读取记录之前获得文件位置,则可以将信息存储到 std::map<unsigned int, Engine>
中并使用文件指针作为映射中的索引。
我说过这闻起来像它可以使用数据库吗?
另一个想法是读入所有记录并将它们推入std::vector
。创建一个 std::map<unsigned int, unsigned int>
以将矢量索引映射到文件位置。
仍然感觉你应该使用数据库。
通过将引擎记录放入向量中,您可以创建其他索引表(数据库可以为您创建索引表)。例如,std::map<string, unsigned int>
将引擎类型映射到矢量索引。
研究数据库理论,尤其是范式。当您使用数据库时,您将从这些知识中获益良多。