【问题标题】:structure to files and back again结构到文件并再次返回
【发布时间】:2014-06-21 14:13:36
【问题描述】:

我有一个程序可以将一些字符串和整数放入一个结构中。 现在我想这样做,如果程序打开,它会从文件中获取所有信息,如果程序关闭,我想将所有信息保存到同一个文件中,以便下次可以找到它。

最好的方法是使用一个文件将其全部放入或每个变量一个单独的文件?

如果我发现了这一点,我需要知道如何找到特定的行,而不是从那里读取信息。 (就像第 59 行的名称在结构体数组中排在第 59 位。), 然后我必须覆盖某些信息,例如玩过的游戏数量以及赢、输或平局的数量。 (这是一个小游戏。)

结构如下:

struct Recgame{
    char name[20];
    char surname[20];
    int games;        //needs to be overwritable in file
    int won;          //needs to be overwritable in file
    int same;         //needs to be overwritable in file
    int lost;         //needs to be overwritable in file
    int place;        //needs to be overwritable in file
            int money;        //needs to be overwritable in file
} info[100];

【问题讨论】:

  • 你可能想查找“数据库”,可能是 SQLite。
  • 由于你的结构是一个 POD,你可以通过使用 fwrite 将你的结构二进制写入文件来摆脱它(如果你不打算通过文本文件修改它),这可能会节省给你一些空间。
  • 文件是程序写的,不是我写的
  • 这称为“序列化”。您现在可以对该主题进行大量研究。
  • 程序以哪种格式写入?二进制还是文本?

标签: c++ file input line output


【解决方案1】:

执行此操作的 C++ 方法是为 struct Recgame 编写流插入器和流提取器。 原型是:

std::ostream& operator<<( std::ostream& out, const Recgame& recgame );
std::istream& operator>>( std::istream& in, Recgame& recgame );

在此之后,您可以轻松地将信息写入文件

ofstream file("afile.txt");
for( int i=0; i<n; ++i ) // n should be the number of the objects
    file << info[i];

写作的实现可以是:

std::ostream& operator<<( std::ostream& out, const Recgame& recgame )
{
    // make sure, that the char-arrays contain a closing char(0) -> ends
    out << recgame.name << "\n";
    out << recgame.surname << "\n";
    out << recgame.games << " " << recgame.won << " " << recgame.same << " " << 
      recgame.lost << " " << recgame.place << " " << recgame.money << "\n";
    return out;
}

阅读提取器的实现

std::istream& operator>>( std::istream& in, Recgame& recgame )
{
    in >> std::skipws;  // skip leading spaces
    in.getline( recgame.name, 20 ).ignore( std::numeric_limits< std::streamsize >::max(), '\n' ); // requires #include <limits>
    in.getline( recgame.surname, 20 ).ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
    in >> recgame.games >> recgame.won >> recgame.same >> 
        recgame.lost >> recgame.place >> recgame.money;
    return in;
}

从文件中读取:

ifstream file("afile.txt");
int n = 0; // number of read objects
for( ; n < N && file >> info[n]; ++n ) // -> const int N = 100;
    ;
if( file.eof() )
    cout << "Ok - read until end of file\n";
cout << "read " << n << " objects" << endl;

【讨论】:

  • 感谢它的工作。我可以将结束字符放在 out
  • 不! char(0) 不会被写入文件。 char(0) 是分隔符,用于标记内存中文本的结尾。更好:使用 std::string
  • 所以我可以做一些事情,比如复制到一个变量和广告“/0”并将其复制到文件中
  • 问题是:Recgame.name和Recgame.surname的内容是从哪里来的?如果您从 std::cin 读取它 - 比如 cin.getline( recgame.name, 20 ) - 一切正常,因为 getline 在文本末尾附加了一个 char(0) 。大多数字符串函数以相同的方式执行此操作。如果你使用 std::string (我的建议)你没有这样的问题。
  • 我只使用普通的getline,所以有问题。我可能会先读取它,然后将 /0 替换为空格
【解决方案2】:

您可以使用 C 中的 fwrite 函数将结构写入二进制文件,然后使用 fread 再次读取它。

如果要使用 C++ 风格的文件 I/O,则需要重载 &lt;&lt;&gt;&gt; 运算符。

【讨论】:

  • 对不起,你说的某些行是什么意思?如果要访问文件中的特定位置,可以使用fseek 函数来实现。在 Google 中搜索“C/C++ 中的随机访问二进制文件”以获取更多信息。
  • 你想从文件中读取特定的行吗?只喜欢第 10 个条目的名称?
  • 是的,哈桑,我想获取来自该行的所有变量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 2011-02-20
  • 2011-06-11
相关资源
最近更新 更多