用C ++读取文本文件的特定部分

时间:2016-06-28 08:00:22

标签: c++ fstream

我正在使用<fstream>读取文件,并且该文件包含以下行:

Name=Cecil
Age=34
Born=London
//etc.

为了举例说明,我想将34分配给变量int age。这意味着我必须找到以Age开头的行,然后在等号后提取值34

稍后我想在程序中更改此值,并将其替换为文件,因此34将成为例如35,所以我必须再次找到此特定部分文件并写在那里。

这似乎是一项基本任务,但到目前为止我找不到任何好的例子。也许最好将我的数据存储为JSON或XML,并为此目的使用库?

4 个答案:

答案 0 :(得分:2)

这是基本需求,但不是基本实现,因为文件只是字节流而没有结构。这意味着您需要实现一些算法来解释/解析写入的数据。您应该知道,您无法删除文件中的内容,也无法插入;我的意思是没有单一的操作可以解决这个问题,并且在你的情况下会出现问题,因为如果你想用34替换34,那么信息的长度是不同的,你想要删除一个char(不可能)和替换另一个(这是可能的);将103替换为103时的原因相同。这就是为什么数据库适用于:让您轻松管理结构化信息。

好的,这并不意味着这是不可能的,因为数据库使用文件。也许,首先,您可以:读取所有文件并将其解析为内存中的结构化数据,然后管理该数据,并在需要时将数据写入新文件中。当然,如果您有太多数据,这不是一个严肃的实现。

答案 1 :(得分:1)

这只是一些一般性的推理,作为答案的答案“也许它会更好......”:

任何简单的实现都会有点脆弱,但是如果您对输入文件有很好的控制,并且可能存在数据损坏的风险并不会给您带来太多麻烦(即损坏程度低且易于恢复/修复),你甚至可以通过更换字符串来逃避,搜索“Age = 34 \ n”并将其替换为“Age = 35 \ n”(如果文件中只有单个Age行,否则你需要先找到正确的人)。 ..首先将整个文件读入内存,然后在替换后将其写回。

使用JSON将为您提供更多的结构安全性(没有机会意外更改“CarnAge = 34”而不是“Age = 34”),但JSON仍然可以在纯文本编辑器中编辑(如果你足够小心) )。此外,JSON是与Web服务交换数据的非常流行的方式。这段也适用于XML,虽然在纯文本编辑方面我认为JSON对于非程序员来说更容易学习。所以“ini”会这样做,但我仍然喜欢JSON。

最后,如果这更严重,考虑一些数据库会很有意义。这些是经过验证的解决方案,可以非常有效地存储/修改/获取数据,使用文件I / O比使用简单的读/写整个文件更高效(DB正在以允许他们通过覆盖部分内容来修改内容的方式处理文件,通过保留周围的储备空间并具有完全重构某些文件的一部分的机制)。此外,大多数数据库都是ACID,因此可以“免费”为您的应用添加额外的稳健性。您无法以纯文本格式编辑数据(但您仍然可以在某个工作表中准备数据,并通过某些数据库管理器工具导入它们。)

为什么要避免一些常见的数据库 - 我能想到的 - 的唯一原因是:1)性能(在特殊情况下,优秀的程序员将胜过专业的数据库引擎,但大多数时候它不值得付出巨大的努力), 2)项目太小/教程,所以虽然集成例如“sqlite”并不困难,但只需读取整个文件并替换字符串就更简单了。但是,例如我使用U ++框架编写我的C ++项目,因此添加SQL将是轻而易举的几行,没有大麻烦......

答案 2 :(得分:0)

由于您的数据看起来像键值对,所以这是一种面向对象的方式:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

struct DATA
{
    struct PAIR
    {
            string m_szComponentSeparator;
            string m_szKey;
            string m_szValue;
            PAIR()
            {
                    m_szComponentSeparator = "=";
            }
            void Read(ifstream &_inFile)
            {
                    string szLine;
                    _inFile >> szLine;
                    size_t pos = szLine.find(m_szComponentSeparator);
                    m_szKey = szLine.substr(0, pos);
                    m_szValue = szLine.substr(pos + 1);
            }
            void Write(ofstream &_outFile)
            {
                    _outFile << m_szKey << m_szComponentSeparator << m_szValue << endl;
            }
            int To_int()
            {
                    return atoi(m_szValue.c_str());
            }
            void SetAs_int(int _iValue)
            {
                    char szBuf[32] = {0};
                    snprintf(szBuf, sizeof(szBuf), "%d", _iValue);
                    m_szValue = szBuf;
            }

    };

    PAIR m_stName;
    PAIR m_stAge;
    PAIR m_stBorn;
    void Read(string _szFilepath)
    {
            ifstream inFile(_szFilepath.c_str());
            m_stName.Read(inFile);
            m_stAge.Read(inFile);
            m_stBorn.Read(inFile);
    }
    void Write(string _szFilepath)
    {
            ofstream outFile(_szFilepath.c_str());
            m_stName.Write(outFile);
            m_stAge.Write(outFile);
            m_stBorn.Write(outFile);
    }
    void Print()
    {
            cout << m_stName.m_szKey << m_stName.m_szComponentSeparator << m_stName.m_szValue << endl;
            cout << m_stAge.m_szKey << m_stAge.m_szComponentSeparator << m_stAge.m_szValue << endl;
            cout << m_stBorn.m_szKey << m_stBorn.m_szComponentSeparator << m_stBorn.m_szValue << endl;
    }
};
int main()
{
    string szInputFile = "in.txt";
    string szOutputFile = "out.txt";

    DATA oData;
    oData.Read(szInputFile);
    oData.Print();

    int age = oData.m_stAge.To_int();
    age = 35;
    oData.m_stAge.SetAs_int(age);

    cout << "after modification:" << endl;
    oData.Print();

    oData.Write(szOutputFile);

    return 0;
}

//Output:
Name=Cecil
Age=34
Born=London
after modification
Name=Cecil
Age=35
Born=London

答案 3 :(得分:0)

尝试这个

ifstream ifs("e:\\file.txt");
vector<string> file;    
string temp;

while(getline(ifs, temp))
{
    if(temp.compare(0,4,"Age=")==0)
        temp.replace(0, sizeof("Age=125"),"Age=125");

        file.push_back(temp);
}
ifs.close();

ofstream ofs("e:\\file.txt");
for(auto begin = file.begin(), end = file.end(); begin!=end; begin++)
    ofs << *begin << endl;

ofs.close();