I have some problems, I'm getting these errors (marked in the code):
identifier "cerr" is undefined
no operator "<<" matches these operands
Why?
#include "basic.h"
#include <fstream>
using namespace std;
int main()
{
ofstream output("output.txt",ios::out);
if (output == NULL)
{
cerr << "File cannot be opened" << endl; // first error here
return 1;
}
output << "Opening of basic account with a 100 Pound deposit: "
<< endl;
Basic myBasic (100);
output << myBasic << endl; // second error here
}
You must include iostream in order to use cerr.
See http://en.cppreference.com/w/cpp/io/basic_ostream.
You need to add this at the top :
#include <iostream>
for cerr and endl
include iostream for cerr support.
And there is no implementation of operator << for class Basic. You'd have to make that implementation yourself. See here.
#include <fstream>
#include <iostream>
#include "basic.h"
std::ostream& operator<<(std::ostream &out, Basic const &x) {
// output stuff: out << x.whatever;
return out;
}
int main() {
using namespace std;
ofstream output ("output.txt", ios::out);
if (!output) { // NOT comparing against NULL
cerr << "File cannot be opened.\n";
return 1;
}
output << "Opening of basic account with a 100 Pound deposit:\n";
Basic myBasic (100);
output << myBasic << endl;
return 0;
}
Related
So I have the following code:
#include <iostream>
#include <fstream>
#include <string>
void writeSingle(std::fstream &myFileStream)
{
myFileStream.open("my_file2", std::ios::trunc);
if (!myFileStream)
{
std::cout << "File not created!\n";
}
else
{
std::cout << "File created successfully!\n";
myFileStream << "Line 1\n";
myFileStream << "Line 2\n";
myFileStream << "Line 3\n";
myFileStream.close();
}
}
int main()
{
std::fstream myFileStream;
writeSingle(myFileStream);
return 0;
}
My question is, whenever I use std::ios::trunc, be it in a combination with app (std::ios::trunc | std::ios::app) and regardless to whether the file exists or not, the program
ends up in the !myFileStream block. With only std::ios::out and std::ios::app the program works as expected.
Why is it so? Can someone provide at least one working example with std::ios::trunc?
Thanks.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
int main() {
fstream a_file_that_will_be_working_with("storage.txt");
if (a_file_that_will_be_working_with.is_open()) {
cout << "is open";
}
else
{
cout << "is not open";
}
a_file_that_will_be_working_with << "first text" << endl;
a_file_that_will_be_working_with << "second text" << endl;
while (a_file_that_will_be_working_with)
{
// read stuff from the file into a string and print it
string strInput;
a_file_that_will_be_working_with >> strInput;
cout << strInput << '\n';
}
return 0;
}
What have I done wrong?
When I use ifstream to read from a file it works, but it doesnt for fstream, I thought fstream is both ofstream and ifstream combined.
See https://en.cppreference.com/w/cpp/io/basic_fstream for an example.
You need to "rewind" the file to read just written stuff (s.seekp(0);).
I've been trying to write a code to read from a file line by line:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream jin("Story.txt");
// ins.open("Story.txt", ios::in);
if (!jin)
{
cout << "File not opened" << endl;
return 1;
}
else{
char a[100];
do
{
jin.getline(a, 100);
cout << a << endl;
}
while (!jin.eof());
jin.close();
return 0;
}
}
However, on executing this program on Visual Studio Code on Windows, it behaves as infinite loop.
Can someone tell what's wrong?
(I am sure that the file Story.txt exists, no doubt about that)
When std::istream::getline has read 100-1 characters (without finding a newline,\n), it will set the failbit on the stream. This prevents further reading on the stream (unless you reset that state). It does however not set eofbit so you are now in a bit of a pickle. The failbit prevents further reading, and eof() returns false, because eofbit is not set - it will therefore loop indefinitely.
If at least one of the lines in Story.txt is longer than 99 chars, the above is what will happen.
The easiest way out is to use a std::string and std::getline instead:
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream jin("Story.txt");
if(!jin) {
std::cerr << "File not opened: " << std::strerror(errno) << std::endl;
return 1;
}
std::string a;
while(std::getline(jin, a)) {
std::cout << a << '\n';
}
return 0;
}
If you really do not want to use std::getline and std::string, you can, but it's much harder:
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
int main() {
std::ifstream jin("Story.txt");
if(!jin) {
std::cerr << "File not opened: " << std::strerror(errno) << std::endl;
return 1;
}
char a[100];
while(true) {
jin.getline(a, 100);
std::cout << a; // output what we got
if(jin) {
// got a complete line, add a newline to the output
std::cout << '\n';
} else {
// did not get a newline
if(jin.eof()) break; // oh, the end of the file, break out
// reset the failbit to continue reading the long line
jin.clear();
}
}
}
jin.eof() will only return true if a eof-token is found, and this will not happend unless the file is open. That is what causing your infinite loop.
Then you would probably want something like this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream jin{"Story.txt"};
if (!jin)
{
cout << "File not opened" << endl;
return 1;
}
for (std::string a; std::getline(jin, a);) { // Read every line
cout << a << "\n";
}
// jin is closed when going out of scope so no need for close();
return 0;
}
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.
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;
}
May I know which part of both programs causes the problem and how may I solve it?
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.)
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);
}
}
I am trying a reasonably simple program to test binary input/output. I am basically writing a file with a header (string) and some data (doubles). The code is as follows:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main() {
typedef std::ostream_iterator<double> oi_t;
typedef std::istream_iterator<double> ii_t;
std::ofstream ofs("data.bin", std::ios::in);
//-If file doesn't exist, create a new one now
if(!ofs) {
ofs.open("data.bin", std::ios::out|std::ios::binary|std::ios::app);
}
else {
ofs.close();
ofs.open("data.bin", std::ios::out|std::ios::binary|std::ios::app);
}
//-Write a header consisting of length of grid subdomain and its name
///*
const std::string grid = "Header";
unsigned int olen = grid.size();
ofs.write(reinterpret_cast<const char*>(&olen), sizeof(olen));
ofs.write(grid.c_str(), olen);
//*/
//-Now write the data
///*
std::vector<double> data_out;
//std::vector<std::pair<int, int> > cell_ids;
for(int i=0; i<100; ++i) {
data_out.push_back(5.0*double(i) + 100.0);
}
ofs << std::setprecision(4);
std::copy(data_out.begin(), data_out.end(), oi_t(ofs, " "));
//*/
ofs.close();
//-Now read the binary file; first header then data
std::ifstream ifs("data.bin", std::ios::binary);
///*
unsigned int ilen;
ifs.read(reinterpret_cast<char*>(&ilen), sizeof(ilen));
std::string header;
if(ilen > 0) {
char* buf = new char[ilen];
ifs.read(buf,ilen);
header.append(buf,ilen);
delete[] buf;
}
std::cout << "Read header: " << header << "\n";
//*/
///*
std::vector<double> data_in;
ii_t ii(ifs);
std::copy(ii, ii_t(), std::back_inserter(data_in));
std::cout << "Read data size: " << data_in.size() << "\n";
//*/
ifs.close();
//-Check the result
///*
for(int i=0; i < data_out.size(); ++i) {
std::cout << "Testing input/output element #" << i << " : "
<< data_out[i] << " " << data_in[i] << "\n";
}
std::cout << "Element sizes: " << data_out.size() << " " << data_in.size() <<
"\n";
//*/
return 0;
}
The problem is that when I try to write and read (and then print) both the header and the data it fails (I confirmed that it doesn't read the data then, but displays the header correctly). But when I comment out one of the write sections (header and/or data), it displays that part correctly indicating the read worked. I am sure I am not doing the read properly. Perhaps I am missing the usage of seekg somewhere.
The code runs fine for me. However you never check if the file is successfully opened for writing, so it could be silently failing on your system. After you open ofs you should add
if (!ofs) {
std::cout << "Could not open file for writing" << std::endl;
return 1;
}
And the same thing after you open ifs
if (!ifs) {
std::cout << "Could not open file for reading" << std::endl;
return 1;
}
Or something along those lines. Also I do not understand why you check if the file exists first since you do the same whether it exists or not.
This should work
#include <iostream>
using std::cout;
using std::cerr;
using std::cin;
using std::endl;
#include <fstream>
using std::ifstream;
#include <cstdint>
int main() {
ifstream fin;
fin.open("input.dat", std::ios::binary | std::ios::in);
if (!fin) {
cerr << "Cannot open file " << "input.dat" << endl;
exit(1);
}
uint8_t input_byte;
while (fin >> input_byte) {
cout << "got byte " << input_byte << endl;
}
return 0;
}