File object with fstream object is not created - c++

I am trying to create a binary file as follows:
#include <iostream>
#include<fstream>
using namespace std;
int main()
{
cout<<"Hello World";
fstream fileObj = std::fstream("test_File.db", std::ios::in | std::ios::out | std::ios::binary);
if(fileObj)
std::cout<<"success";
else
std::cout<<"fail";
return 0;
}
But fileObj is not created and always else part is executed. Please guide if I am missing anything.

A stream opened with in | out | binary does not create a file that does not exist. You should get into the habit of reading the documentation!
Try in | out | app | binary (assuming you want existing contents to be kept; also get into the habit of clearly stating your goal/requirements).
And there is no need to initialise from a temporary like that; just instantiate the object in the usual manner, e.g.
std::fstream fileObj(
"test_File.db",
std::ios::in | std::ios::out | std::ios::app | std::ios::binary
);

Related

fstream seekp() not working when the file is opened in ios::in and out mode

I want to replace some certain portion (in the middle) in a binary file. If I use ostream out("file.bin",ios::binary) ,it will delete the old file and creat a new one. But if I use fstream out("file.bin",ios::binary|ios::in|ios::out) ,seekp() will not go to the right place and tellp() always return -1. So is there any way to replace some certain portion in a file?
Thank you in advance.
You must open the stream with the at the end, in and out bits set:
std::fstream out("file.bin", ios::binary | ios_base::ate);
This will prevent your file to be reset at opening; then, using seekp and unformatted output functions you will be able to edit it in the middle.
This example outputs stackovstrlow, showing how to chain all steps together:
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
int main()
{
// create the bin file
{
std::string str("stackoverflow\n");
std::ofstream file("file.bin", std::ios_base::binary);
file.write(str.c_str(), str.length() + 1);
}
// edit the bin file "in the middle"
{
std::fstream file("file.bin", std::ios_base::in | std::ios_base::out | std::ios_base::ate);
file.seekp(7);
file.write("str", 3);
}
// read and see what we've done
std::ifstream file("file.bin", std::ios_base::binary);
std::vector<char> v(14);
file.read(v.data(), 14);
std::string str(v.cbegin(), v.cend());
std::cout << str;
}
Seeking on file streams is supposed to work although not always. Notably, seeking does fail if the encoding used by the imbue()ed std::locale() is variable width. Quoting from 27.9.1.5 [filebuf.virtuals] paragraph 13:
Effects: Let width denote a_codecvt.encoding(). If is_open() == false, or off != 0 && width <= 0, then the positioning operation fails. ...
Assuming the file was opened OK, it would imply a std::locale with a non-fixed width encoding was used. The approach to avoid this issue is to use the C-locale before opening the file. For example:
std::fstream stream;
stream.imbue(std::locale::classic());
stream.open("file.bin", std::ios_base::binary | std::ios_base::in | std::ios_base::out);

Having trouble outputting file [duplicate]

I am trying to use std::fstream for io to file, and I want to create the file if it doesn't already exist.
std::fstream my_stream
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
if(!my_stream)
std::cout<<"error"<<strerror(errorno);
I get this result:
"No such file or directory."
How can I create the file in this case?
You're specifying std::fstream::in in your call to fstream::open(). This is known to force it to require an existing file.
Either remove std::fstream::in from your mode argument, or specify std::fstream::trunc in addition to the other flags.
It's a little messy but works. Doesn't overwrite the file if it exists but creates a new one if the first open fails.
std::fstream my_stream
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
if(!my_stream)
{
my_stream.open("my_file_name",std::fstream::binary | std::fstream::trunc | std::fstream::out);
my_stream.close();
// re-open with original flags
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
}
else
{
// read something
}
// read/write here

How to set filename parameter as actual filename

I'm wondering how I can set a filename which my function receives as a parameter set as an actual filename.
My Syntax is
std::ofstream file("filename.bin",
std::ios::out | std::ios::trunc | std::ios::binary);
But that will name the file "filename.bin" ofc.
How would I have to write it if I get the filename as parameter and save the filename in a string called SavedFilename. And name the file after the string instead of "filename.bin".
Thanks.
You mean like this?
void foo(const char* filename) {
std::ofstream file(filename,
std::ios::out | std::ios::trunc | std::ios::binary);
// ...
}
foo("filename.bin");

std::fstream doesn't create file

I am trying to use std::fstream for io to file, and I want to create the file if it doesn't already exist.
std::fstream my_stream
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
if(!my_stream)
std::cout<<"error"<<strerror(errorno);
I get this result:
"No such file or directory."
How can I create the file in this case?
You're specifying std::fstream::in in your call to fstream::open(). This is known to force it to require an existing file.
Either remove std::fstream::in from your mode argument, or specify std::fstream::trunc in addition to the other flags.
It's a little messy but works. Doesn't overwrite the file if it exists but creates a new one if the first open fails.
std::fstream my_stream
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
if(!my_stream)
{
my_stream.open("my_file_name",std::fstream::binary | std::fstream::trunc | std::fstream::out);
my_stream.close();
// re-open with original flags
my_stream.open("my_file_name",std::fstream::binary | std::fstream::in | std::fstream::out);
}
else
{
// read something
}
// read/write here

fstream in and out on nonexistent file

Is it possible to open an fstream on a file that does not exist with both ios::in & ios::out without getting an error?
To open an fstream on a file that does not exist for input and output (random access) without getting an error, you should provide the flags fstream::in | fstream::out | fstream::trunc in the open (or constructor) call. Since the file does not already exist, truncating the file at zero bytes is no drama.
You may want an error when opening a file that doesn't exist when specifying only ios::in since you'll never be able to read from the stream so failing early in this case will prevent surprise failures later on.
The answer to your question unfortunately is: "No", this is not possible in a single C++ statement.
Yes, many people will answer, that you can use the combined flags fstream::in | fstream::out | fstream::trunc. But that answer is nonsense. fstream::trunc means, that the output file will be truncated to size zero upon opening. But then, why would you like to open an empty file for reading and writing? Except for the rare case, that you need a file as a temporary store for some of your application's data, that you will first write and later read back, there is no use for this flag combination.
Some people recommend to first try to open with fstream::in | fstream::out (and possible further flags like fstream:app or fstream::binary as needed) and then check the file's error status: If the file could not be opened, then re-try the open operation including | fstream::trunc. This solution has several caveats, however. For example, if your file system is mounted via NFS, the first attempt to open the file in read/write-mode might fail due to temporary network issues. If the second attempt (the one including the fstream::trunc flag) then succeeds, there goes your wounderful data, that you have collected so far.
The safe solution is to first open the file for appending only (which will create the file, if it doesn't exist, but will not truncate it) and then close it immediately and open it a second time in read-write mode. This can be achieved with the following code: Note, that an ofstream is first constructed and then immediately discarded.
std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ostream::app);
std::fstream file(filename);
Alternatively, if you need further flags, like binary, use:
std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ofstream::app | std::fstream::binary);
std::fstream file(filename, std::fstream::in | std::fstream::out | std::fstream::binary);
I hope, that in C++25 (or whichever standard is next), they finally add a flag std::fstream::create to create non-existant output files, if read-write-mode is requested.
#include <fstream>
ofstream out("test", ios::out);
if(!out)
{
cout << "Error opening file.\n";
return 1;
}
ifstream in("test", ios::in);
if(!in)
{
cout << "Error opening file.\n";
return 1;
}
If an error occurs the message is displayed and one (1) is returned. However it is possible to compile and execute just ofstream out("test", ios::out); and ifstream in("test", ios::in); without any errors. Either way the file test is created.
#include <iostream>
#include <fstream>
using namespace std;
int main () {
fstream f("test.txt", fstream::in | fstream::out);
cout << f.fail() << endl;
f << "hello" << endl;
f.close();
return 0;
}
This code will print 1 and will not create "test.txt" file, if it does not exit. So it is not possible to open and fstream on a file that does not exist without getting an error.
std::fstream f("test.txt", std::ios_base::out);
f.close(); //file now exists always
f.open("test.txt", fstream::in | std::ios_base::out);
//f is open for read and write without error
I haven't checked to guarantee that it will open without error, but I feel pretty confident that it should.