【问题标题】:From a file, how do I read from a certain point in C++从文件中,我如何从 C++ 中的某个点读取
【发布时间】:2015-12-17 22:19:04
【问题描述】:

我想做什么: 我需要在 void main() 中创建 3 个自动对象。 对于每个对象,我都有一个 txt 文件中的信息。

如何获取每个对象的信息(引擎、最大速度...等)。如何在创建第二个对象时跳过阅读“引擎”以及如何跳过整个汽车。谢谢!

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 类中的 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

【问题讨论】:

  • 纯文本不是一个好的序列化格式。使用允许表示结构信息的文件格式(例如XMLJSON)。
  • 顺便说一句,main 函数返回int。总是。因此,您应该将代码放入您的 int main 函数中。

标签: c++ file oop ifstream


【解决方案1】:

在文件格式中,没有有效的方法来定位给定的记录。记录是可变大小的,例如,一个引擎速度为 100(3 个字符),而另一个记录为 80(2 个字符)。

由于每个字段都位于单独的行上,因此您可以阅读每个文本行,在文本的开头搜索“引擎”。

这个项目闻起来像是可以使用数据库。

如果您必须逐行阅读,您不妨逐条阅读。也就是说,让记录对象从文件中读取其成员。

如果您在读取记录之前获得文件位置,则可以将信息存储到std::map<unsigned int, Engine> 中,并将文件指针用作映射的索引。

我有没有说这闻起来像可以使用数据库?

另一个想法是读入所有记录并将它们推入std::vector。创建一个std::map<unsigned int, unsigned int> 将向量索引映射到文件位置。

你还是觉得应该使用数据库。

通过将引擎记录放入向量中,您可以创建其他索引表(数据库可以为您创建索引表)。例如,std::map<string, unsigned int> 将引擎类型映射到向量索引。

研究数据库理论,尤其是范式。当您使用数据库时,您将从这些知识中受益匪浅。

【讨论】:

  • 谢谢!这是一个学校项目,我必须使用我上面发布的确切文字。
【解决方案2】:

如何跳过阅读“引擎”?

如果您不想检查读取的内容,可以使用 std::ifstream::ignore 和自定义分隔符:

f.ignore(std::numeric_limits<std::streamsize>::max(), ':');

但是看到这些键被: 或它们的值分隔,您也可以使用std::getline 读取直到: 或简单的operator&gt;&gt; 读取到std::string 直到空格,包括: 然后检查一下。

如何跳过整辆汽车?

如果您的意思是将另一个 Auto 写入文件,您可以使用附加模式打开文件 - 使用 std::ios_base::out | std::ios_base::app

另一方面,如果您的意思是阅读信息,您可以通过重复调用(在循环中)跳过看似恒定的行数:

f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

编辑:

要读取: 之后的值,您可以使用:

  1. operator&gt;&gt; - 格式化提取,然后是 std::getlinestd::istream::ignore 行的其余部分(\n 作为分隔符),因此下一个 std::getline 正确读取下一行
  2. std::getline\n 分隔符读取该行的其余部分,然后使用 std::istringstream 解析它并进行格式化提取。

在这两种情况下,你都可以知道值后面是否有一些多余的字符。

【讨论】:

  • 谢谢 :) 如何使用 getline 方法获取 : 后的 char 或 int ?就像你说的,我认为这是获取信息的最佳方式。
  • 编辑了我的答案,只是一遍又一遍的相同功能。
  • 很抱歉我再次发帖。就像我说的,我认为我没有发布正确的问题。我仍然不确定如何进行。我想我需要一个类似于我的示例代码,或者通过 Skype 与某人交谈。
  • 没关系,你已经得到了另一个答案(基本上就是我所说的),我希望这会有所帮助。但是你仍然可以接受这个(理论上是正确的)。我可以添加示例。
  • 我可以让你通过Skype帮助我吗?什么时候,如果你有时间。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多