1

2つのプログラムを作成して同時に実行する必要がありwrite.cppます。read.cpp1つはファイルに書き込み(上書き)し、もう1つはファイルから読み取ります。

基本的に、ファイルには常に1行しかありません。

write.cpp操作は正常に実行されますが、read.cpp何も表示されません。を使用するtail -fと、誤った結果も表示されます。

write.cpp:

#include <stdio.h>
#include <ctime>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  ofstream myfile;
  int i = 70;
  char c;
  while(i <85)
  {
      myfile.open ("example.txt");
      c = i++;
      myfile << c << endl;
      myfile.close();
      sleep(1);
  }
  return 0;
}

read.cpp:

#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>

using namespace std;

int main () {
  string line;
  ifstream myfile ("example.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      sleep(1);
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file";

  return 0;
}

両方のプログラムのどちらの部分が問題を引き起こしているのか、そしてどのように解決できるのかを知ることができますか?

4

2 に答える 2

3

ライターで正しいことを行っていますが、ファイルの最後まで読み取ると、fail条件が設定されるまで入力ストリームは使用できなくなります。最善の解決策は、おそらくライターで行っていることを正確に実行することです。読み取りループで毎回ファイルを開いたり閉じたりします。

ファイルが空になる瞬間があることに注意してください。ライターで書き込むためにファイルを開くと、ファイルは切り捨てられ、リーダーがこの瞬間に正確に読み取ろうとすると、空のファイルが見つかります。sleep(これは大きな問題ではありません。空の行が見つかった場合はスキップする可能性があることに注意してください。)

于 2013-02-20T10:30:37.343 に答える
2

以前の質問に対する私の回答に詳細を追加するために、 のファイルを使用することを主張する場合に、Boostのプロセス間通信を使用してこれを実現する方法を次に示します。

ライターは次のようになります。

#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <fstream>
#include <iostream>

int main()
{
    using namespace boost::interprocess;
    std::string line, shared_filename = "shared";

    {
        std::ofstream create_shared_file(shared_filename.c_str());
    }

    for (;;)
    {
        std::cout << "Enter some text: ";
        std::cin >> line;

        try
        {
            file_lock lock(shared_filename.c_str());
            scoped_lock<file_lock> lock_the_file(lock);

            std::ofstream shared_file(shared_filename.c_str(), std::ofstream::trunc);
            shared_file << line << std::endl;
            shared_file.flush();
        }
        catch (interprocess_exception const& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
}

対応するリーダー:

#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <fstream>
#include <iostream>
#include <unistd.h>

int main()
{
    using namespace boost::interprocess;
    std::string line, shared_filename = "shared";

    for (;;)
    {
        try
        {
            file_lock lock(shared_filename.c_str());
            std::cout << "Waiting for file lock..." << std::endl;
            sharable_lock<file_lock> lock_the_file(lock);
            std::cout << "Acquired file lock..." << std::endl;

            std::ifstream shared_file(shared_filename.c_str());
            shared_file >> line;

            if (line.empty())
            {
                std::cout << "Empty file" << line << std::endl;
            }
            else
            {
                std::cout << "Read: " << line << std::endl;
            }
        }
        catch (interprocess_exception const& e)
        {
            std::cerr << "Could not lock " << shared_filename << ": " << e.what() << std::endl;
        }

        std::cout << "Sleeping..." << std::endl;
        sleep(2);
    }
}
于 2013-02-21T05:22:09.873 に答える