Switch files in variables (cpp) - c++

my Problem is best explained in code:
fstream One;
fstream Two;
fstream Three;
One.open(path1, ios_base::out);
Two.open(path2, ios_base::out);
Three.open(path3, ios_base::out);
As you can see above i have three fstream variables and I've loaded three seperate files into them.
Now I want to Change some files.
One=Three;
Three=Two;
So that when i use One file, i will be using file from path3.
I know that i probably can't assign fstreams like that. And here's my question: how can i do that?
Sorry for my english, if something is not clear then simply comment.
Thanks in advance!

#include <algorithm>
#include <fstream>
using namespace std;
auto main() -> int
{
auto path1 = "a.txt";
auto path2 = "b.txt";
auto path3 = "c.txt";
ofstream one;
ofstream two;
ofstream three;
one.open(path1);
two.open(path2);
three.open(path3);
swap( one, two );
two << "Two" << endl;
}
Things to note:
Use ofstream for pure output streams.
Don't use global variables.
Ideally check for failures (not done in the above code).

You could use pointers to refer to different fstream objects. I would suggest you to stay with stack allocation:
fstream One;
fstream Two;
fstream Three;
One.open(path1, ios_base::out);
Two.open(path2, ios_base::out);
Three.open(path3, ios_base::out);
And then you can use pointers like this:
fstream* A = &One;
fstream* B = &Two;
/*...*/
A = &Three;
I think this answers your question, but I think what you are really looking for is a way to use the same function with different fstreams. To do this, simply pass them as reference parameters:
void foo(fstream& fs){/*...*/}
And then call it with whatever fstream you like:
foo(A);
foo(B);
PS: and even if the fstreams are global variables (I would strongly suggest to change this) you can still pass them as parameters to functions.

Related

How to write out to a file and make it return the file

int fileReading(string signalFile){
ofstream fileName;
fileName.open(signalFile, ios::in | ios::binary);
//does more stuff here
fileName.close();
return 0;
}
How would I create a new file and switch the return type of the function to a file?
Do I need to create a class for this?
The easiest and probably the most consistent thing to do is to have your function take an fstream as argument (by reference) and then return it,
fstream& fileReading(fstream& strm)
{
// process it here
return strm;
}
This way you are not mixing file names with streams, so your function does only one thing: process a stream. Once you defined your function, you can use it like
fstream fileName("test.txt", ios::in | ios::binary); // we open the stream
fileReading(fileName); // and process the stream, will close automatically at exit from scope
If you try to return a local fstream (i.e. from inside a function), the compiler won't be able to (unless you use C++11), since fstream is non-copyable. In C++11 the compiler will use move semantics and move your local fstream into the returned stream. So in principle this should work:
fstream fileReading(const string& signalFile)
{
fstream fileName;
fileName.open(signalFile, ios::in | ios::binary);
//does more stuff here
// fileName.close(); // do not close it here
return fileName;
}
Then use as
fstream f = fileReading("test.txt");
However, the support for moveable streams seems to be broken in g++4.9 (works in g++5 and clang++). That's why the best is just to pass the stream by reference and return the reference.

How to use insertion operator with a shared_ptr pointer of an ifstream object?

I am trying to read from a file using a shared_ptr pointer. I don't know how I can use insertion operator with it. Here is the code:
#include <iostream>
#include <regex>
#include <fstream>
#include <thread>
#include <memory>
#include <string>
#include <map>
using namespace std;
int main()
{
string path="";
map<string, int> container;
cout<<"Please Enter Your Files Path: ";
getline(cin,path);
shared_ptr<ifstream> file = make_shared<ifstream>();
file->open(path,ifstream::in);
string s="";
while (file->good())
{
file>>s;
container[s]++;
s.clear();
}
cout <<"\nDone..."<< endl;
return 0;
}
simply doing:
file>>s;
doesn't work.
How can I get the current value that file is pointing (I don't want to get the whole line, I just need to get the words and number of their occurrences this way).
By the way, I used shared_ptr to avoid closing the file myself, does making a pointer of this type, shared_ptr (smart) will it suffice not to write the file->close() myself ? or they are irrelevant?
The simplest way would be to use the dereference operator *:
(*file) >> s;
But looking at the code, I see no reason whatsoever to use a smart pointer. You could just use an ifstream object.
std::ifstream file(path); // opens file in input mode
Why do you want it to be a pointer? It's that that is causing you pain.
ifstream file;
file.open( ...
...
file>>s;
Streams are intended to be treated as value (rather than pointer types). The file will be closed when the destructor is called on the ifstream.
If you need to pass the stream object round other parts of your code, you simply use references (to the base class):
void other_fn( istream & f )
{
string something;
f>>something;
}
ifstream file;
other_fn( file );
Because the f parameter is a reference, it doesn't attempt to close the stream/file when it goes out of scope - that still happens in the scope that defines the original ifstream object.

Why can't I copy executables like this?

Using C++'s <fstream>, it's pretty easy to copy a text file:
#include <fstream>
int main() {
std::ifstream file("file.txt");
std::ofstream new_file("new_file.txt");
std::string contents;
// Store file contents in string:
std::getline(file, contents);
new_file << contents; // Write contents to file
return 0;
}
But when you do the same for an executable file, the output executable doesn't actually work. Maybe std::string doesn't support the encoding?
I was hoping that I could do something like the following, but the file object is a pointer and I'm not able to dereference it (running the following code creates new_file.exe which actually just contains the memory address of something):
std::ifstream file("file.exe");
std::ofstream new_file("new_file.exe");
new_file << file;
I would like to know how to do this because I think it would be essential in a LAN file-sharing application. I'm sure there are higher level APIs for sending files with sockets, but I want to know how such APIs actually work.
Can I extract, store, and write a file bit-by-bit, so there's no discrepancy between the input and output file? Thanks for your help, it's much appreciated.
Not sure why ildjarn made it a comment, but to make it an answer (if he posts an answer, I will delete this). Basically, you need to use unformatted reading and writing. getline formats the data.
int main()
{
std::ifstream in("file.exe", std::ios::binary);
std::ofstream out("new_file.exe", std::ios::binary);
out << in.rdbuf();
}
Technically, operator<< is for formatted data, except when use it like the above.
In very basic terms:
using namespace std;
int main() {
ifstream file("file.txt", ios::in | ios::binary );
ofstream new_file("new_file.txt", ios::out | ios::binary);
char c;
while( file.get(c) ) new_file.put(c);
return 0;
}
Although, you'd be better off making a char buffer and using ifstream::read / ofstream::write to read and write chunks at a time.

C++ Why won't my sample program create the output file?

I'm writing a small/beta testing program that will be put to use in my much bigger program for a project. It requests the user for an input file name (IE data.txt) and creates an output file named filename.out (IE data.out). I've tried a simple outFile << "text here"; to try it out but it doesn't create output file. I'm sure I'm messing something simple here but I can't figure out what.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
//Global variables
ifstream inFile;
ofstream outFile;
void main()
{
// Requests user for input filename
string inputFile;
cout << "Enter File Name: ";
cin >> inputFile;
string outputFile = inputFile.substr(0, inputFile.find_last_of('.')) + ".out";
// Opens both inputFile and outputFile
inFile.open(inputFile.c_str(), ios::in);
outFile.open(outputFile.c_str(), ios::in);
// Checks for input file
if (!inFile)
{
cout << "Unable to open file" << endl;
exit(1);
}
outFile << "Hello world!";
inFile.close();
outFile.close();
}
Because you're trying to open the file for reading:
outFile.open(outputFile.c_str(), ios::in);
Use ios::out instead.
Why did you make these streams global variables rather than local ones? In C++, it's generally preferred to construct objects as late as possible. If you do this, you have all information available to open the streams right in the constructor, which can take the same arguments as the open() member function.
One difference between std::ifstream and std::ofstream is that their open() member functions and constructors apply a different default opening mode. It's in for std::ifstream and out for std::ofstream. You can always override these, but that would somewhat defeat the reason for using those streams in the first place. You could use std::fstream, too. For that you would always have to supply the opening modes. If you're using std::ifstream and std::ofstream, just skip the opening modes. Here's how this is looks when using the constructors instead of the open() member functions (it looks pretty much the same with the latter):
std::ifstream inFile(inputFile.c_str());
std::ofstream outFile(outputFile.c_str());
It's int main(), even if some compilers allow void.
I have strong objections to using directives. But these objections are not as widely shared as the other opinions listed in this answer.

Passing ofstream object from main program to a class

Here is what I am trying to do:
1) Open an ofstream object in my main body. I can do this no problem.
2) Associate this object with a filename. No problem.
3) Pass this object to a class and send output within this class. I can't do this.
Here is my code. I would appreciate any help. Thanks!
#include <fstream>
#include <iostream>
using namespace std;
typedef class Object
{
public:
Object(ofstream filein);
} Object;
Object::Object(ofstream filein)
{
filein << "Success";
}
int main (int argc, char * const argv[])
{
ofstream outfile;
outfile.open("../../out.txt");
Object o(outfile);
outfile.close();
return 0;
}
You must pass stream objects by reference:
Object::Object( ofstream & filein )
{
filein << "Success";
}
And why are you using a typedef on the class? It should look like this:
class Object
{
public:
Object(ofstream & filein);
};
It is worth mentioning, that in c++0x you will have another options (besides passing by reference or by pointer):
std::move. Streams are not copyable, but you will be able to move them into another place (it depends if streams will implement the move operator, but they probably will).
unique_ptr. Streams are not copyable. When using pointers, a risk of resource leak arises. Using shared_ptr incorporates unnecessary costs when you want to have streams stored in a collection, and nowhere else. Unique_ptr solves this. You will be able to store streams in a collection in safe and efficient way.