从多个函数写入文件并替换值C ++

时间:2018-08-11 18:25:47

标签: c++ c++11

我有一个example.txt文件,它将通过不同的功能在单独的行中使用值进行更新。并且上述三个函数将处于计时器循环中,因此它将连续不断地调用这三个函数,因此这三个函数将需要写入文件,并在其中计算出更新后的值。

为更好地理解,请参见示例方案, 第一次调用函数时,      * Function1在文件的第一行写入值1。      * Function2在文件第二行写入值5。      * Function3在文件第三行写入值7。

现在再次定时器函数再次调用上述三个函数,我期望文件中的以下输出将被写入。

 *Function1 should write value of 8 at first line of the file.
 *Function2 should write value of 9 at second line of the file.
 *Function3 should write value of 10 at third line of the file.

示例程序:

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

  void writeToFile(int seq)
  {
    fstream myfile;
    myfile.open("example.txt",fstream::in | fstream::out | fstream::app );
    myfile << seq <<endl;
    myfile.close();
  }

  void A()
  {
    writeToFile(5);
  }
  void B()
  {
    writeToFile(2);
  }
  void C()
  {
    writeToFile(4);
  }

  //assume timer function called for every 20secs;
  void timer_func()
  {
     A();
     B();
     C();
  }
  int main()
  {        
    timer_func();
    return 0;
  }

请向我建议一些可能的方法。

2 个答案:

答案 0 :(得分:0)

请考虑将文件保存在类中的内存中,并在发生更改时立即将其写入。并记住线程安全性(如果适用)。

答案 1 :(得分:0)

以这种方式做事不是一个好主意,但是如果您愿意的话...

#include <string>  // string
#include <fstream> // fstream
#include <cstdio>  // snprintf
#include <cassert> // assert
#include <cstring> // memset


#define INITIAL_LINE_COUNT 3
#define INITIAL_FILE_NAME "example.txt"


// singleton class that provides writing to the file
class LineWriter
{
private:

    std::fstream m_file;
    int m_line_count;

    // common singleton implementation
    LineWriter() = delete;
    ~LineWriter() = default;
    LineWriter(const LineWriter&) = delete;
    LineWriter& operator = (const LineWriter&) = delete;
    LineWriter(LineWriter&&) = delete;
    LineWriter& operator = (LineWriter&&) = delete;

    LineWriter(const std::string& filename, int line_count)
    {
        m_file.exceptions(std::fstream::badbit);
        m_file.open(
            filename,
            std::fstream::out | std::fstream::binary
        );

        // fill the file with empty 16-byte length strings ended by CRLN
        {
            for (int i = 0; i < line_count; ++i)
            {
                m_file.write("               \r\n", 16);
            }
        }

        m_line_count = line_count;
    }

public:

    void write(int line, int value)
    {
        // just to check that everything is ok
        assert(m_file.is_open());
        assert(line <= m_line_count && line > 0);

        char buffer[14];

        int size = std::snprintf(buffer, 14, "%d", value);

        // calculate position of line
        // just simple (line - 1) * 16
        int pos = (line - 1) << 4;

        // clear previous value
        m_file.seekp(pos);
        m_file.write("               ", 14);

        // write new one
        m_file.seekp(pos);
        m_file.write(buffer, size);
    }

    static LineWriter& get_instance()
    {
        static LineWriter instance(INITIAL_FILE_NAME, INITIAL_LINE_COUNT);

        return instance;
    }
};

void write_to_file(int line, int value)
{
    LineWriter::get_instance().write(line, value);
}

void call_a() { write_to_file(1, 5); }
void call_b() { write_to_file(2, 13); }
void call_c() { write_to_file(3, 2); }

void timer_func()
{
    call_a();
    call_b();
    call_c();
}

int main()
{
    while (true)
    {
        timer_func();
    }
}

如@ n.m。最好仅缓存所有函数的结果,然后一次写入它们(如果没有太多行)。

如果有很多值和字符串,那么最好使用sqlite之类的数据库引擎,如@JesperJuhl所述。

此示例也不是线程安全的,如果您需要从多个线程中调用此writer,只需在LineWriter :: write方法顶部添加成员互斥锁即可。