I was reading some project code and I found this,here MembersOfLibrary() is a constructor of class MenberOfLibrary
class MembersOfLibrary {
public:
MembersOfLibrary();
~MembersOfLibrary() {}
void addMember();
void removeMember();
unsigned int searchMember(unsigned int MembershipNo);
void searchMember(unsigned char * name);
void displayMember();
private:
Members libMembers;
};
MembersOfLibrary::MembersOfLibrary() {
fstream memberData;
memberData.open("member.txt", ios::in|ios::out);
if(!memberData) {
cout<<"\nNot able to create a file. MAJOR OS ERROR!! \n";
}
memberData.close();
}
What is ios::in|ios::out?
ios::in allows input (read operations) from a stream.
ios::out allows output (write operations) to a stream.
| (bitwise OR operator) is used to combine the two ios flags,
meaning that passing ios::in | ios::out to the constructor
of std::fstream enables both input and output for the stream.
Important things to note:
std::ifstream automatically has the ios::in flag set.
std::ofstream automatically has the ios::out flag set.
std::fstream has neither ios::in or ios::out automatically
set. That's why they're explicitly set in your example code.
memberData.open("member.txt", ios::in|ios::out);
ios::in is used when you want to read from a file
ios::out is used when you want to write to a file
ios::in|ios::out means ios::in or ios::out, that is whichever is required is used
Here's a useful link
http://www.cplusplus.com/doc/tutorial/files/
ios::in and ios::out are openmode flags, and in your case combined with a binary or (|) operation. Thus the file is opened for reading and writing.
Related
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.
i want to create std::ifstream object at runtime as i create new thread ,
ifstream&
getMultiDataReaderStream()
{
ifstream ifs;
ifs.open(m_dataReaderFileName.c_str(), ios::in | ios::binary);
return ifs;
}
void
runThread(void *lpData)
{
ifstream& ifs1 = storeManager.getMultiDataReaderStream();
// code for reading while EOF
ifs1.close();
}
But , I am getting segmentation Fault is something wrong in above code....
See my comment.
There are many ways to fix this. One is this:
void getMultiDataReaderStream(ifstream& ifs)
{
ifs.open(m_dataReaderFileName.c_str(), ios::in | ios::binary);
}
void
runThread(void *lpData)
{
ifstream ifs1;
getMultiDataReaderStream(ifs1);
// code for reading while EOF
ifs1.close();
}
Another is this:
(don't use this, this works, but it's sloppy)
ifstream* getMultiDataReaderStream()
{
ifstream* ifs = new ifstream(m_dataReaderFileName.c_str(), ios::in | ios::binary);
return ifs;
}
void
runThread(void *lpData)
{
ifstream* ifs1 = getMultiDataReaderStream();
// code for reading while EOF
ifs1->close();
delete ifs1;
}
And then with smart ptr:
shared_ptr<ifstream> getMultiDataReaderStream()
{
shared_ptr<ifstream> ifs = shared_ptr<ifstream>(new ifstream(m_dataReaderFileName.c_str(), ios::in | ios::binary));
return ifs;
}
void
runThread(void *lpData)
{
shared_ptr<ifstream> ifs1 = getMultiDataReaderStream();
// code for reading while EOF
ifs1->close();
}
I am sure there are other ways...
According to this: Is std::ofstream movable?
both ifstream and ofstream should be movable, so you should be able to simply "just return it". But, many compilers does not have their stdlibs adapted to C'11 properly. For instance, I've just tried it at http://coliru.stacked-crooked.com/ which seems to have g++ 4.8 and I still cannot move/return any fstream - compiler still insists on using nonexistent copy-constructor instead of move ctor.
This was a known issue that GCC hadn't implemented movability in the streams part. Sorry, I don't know anything more. You'll need to stick with the workarounds until c'11 support gets better.
You should never return a reference (or a pointer) to a local object from a function. In this case, getMultiDataReaderStream() is returning a reference to an object (ifs) that is destroyed as soon as you leave the function. So using it is invalid and leads to undefined behaviour. For instance, a segmentation fault.
I have a C++ code with
ifstream myfile;
myfile.open("input");
and then has commands like:
myfile.getline(inp,256);
Question: How can I modify myfile.open("input") so that myfile is associated with cin instead of "input"?
I don't want to change all myfile.getline commands to cin.getline.
Declaring myfile=cin does not compile.
Use an istream& reference instead:
std::istream& myfile(std::cin);
Separate it out into a function and take the std::istream& as an argument. Then you can execute on both std::cin and myfile as you wish.
You can put your code into a function that takes a reference to a std::istream, e.g.
void process_data( std::istream & istr )
{ ... }
Then you can call this function both with any std::ifstream and with std::cin:
std::ifstream myfile;
...
process_data( myfile );
process_data( std::cin );
If you insist in using an std::ifstream you can replace the std::streambuf of the base std::istream (std::ifstream overloads rdbuf() so you can't use it directly):
std::ifstream file;
if (use_cin) {
file.std::istream::rdbuf(std::cin.rdbuf());
}
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.
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.