Reputation: 4948
I need to write two programs write.cpp
& read.cpp
to run simultaneously. One of them write(overwrite) to a file and the other one reads from it.
Basically, there is always only one line in the file.
write.cpp
performs the operation successfully but read.cpp
doesn't show anything. Using tail -f
also shows incorrect result.
#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;
}
#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;
}
May I know which part of both programs causes the problem and how may I solve it?
Upvotes: 1
Views: 4254
Reputation: 141958
To add some detail to my answer to your previous question, here is how you could use Boost's interprocess communication to achieve this if you insist on using a file for ipc.
A writer may look like this:
#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;
}
}
}
The corresponding reader:
#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);
}
}
Upvotes: 2
Reputation: 154047
You're doing the right thing in the writer, but once you've read to end of file, the input stream becomes unusable until the fail
condition is set. The best solution is probably to do exactly what you're doing in the writer: open and close the file each time in the read loop.
Be aware that there will be a moment when the file is empty; when you open the file for writing in the writer, it will be truncated, and if the reader happens to try to read at precisely this moment, it will find an empty file. (It's no big problem; just be aware of it, maybe skipping the sleep
if you find an empty line.)
Upvotes: 3