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.
Related
as the title suggests, I am having a problem with not being able to read from an input file after passing the ifstream object to a class function. Basically I'm trying to sort a list of numbers using a heap ADT implemented with an array.
int main() {
ifstream infile("input.txt");
HeapSort* heap = new HeapSort(20); // creates a heap (array) with size 20
heap->buildHeap(&infile);
return 0;
}
void HeapSort::buildHeap(ifstream* infile) {
int data;
while (infile >> data) {cout << data << endl;}
infile->close();
}
the error occurs in the conditional of the while loop inside buildHeap. The compiler can't recognize the operator ">>" between an 'int' and an 'ifstream' object. However, strangely enough, if I write that same while loop inside main(), it'll work just fine. Also of note is that if I remove the while loop, the compiler returns no errors. Meaning, simply the act of passing the ifstream object from main to buildHeap is OK.
Please avoid suggesting alternative ways of achieving this. I was asked to not use any special fstream functions like eof(). I can only use the ">>" operator to read from the desired file.
You're passing a pointer to a stream, so you need to dereference it:
while (*infile >> data)
If you want your code to look like what you say you did in main, then you pass a reference:
heap->buildHeap(infile);
//...
void HeapSort::buildHeap(ifstream& infile)
{
int data;
while (infile >> data) { ... }
infile.close();
}
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 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.
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 am geting an an error in the following code it worked fine in visual studio but once i have moved it over to Xcode that uses gcc to compile get this error No matching constructor for initialisation of 'ifstream' i have looked at adding this as a reference rather than a copy as suggested on this site but it still came up with the error.
void getAndSetTextData::GetBannedList(string fileName)
{
bannedWordCount = 0;
ifstream inFile(fileName);
while(inFile >> currentWord)
{
bannedWords.push_back(currentWord);
bannedWords[bannedWordCount++] = currentWord;
}
inFile.close();
}
Any help would be appreciated.
ifstream constructor accepts a const char* as the filename (prior C++11):
ifstream inFile(fileName.c_str());
An additional constructor that accepts a const std::string& as the filename was added in C++11.
Minor point: consider changing argument string fileName to const string& fileName to avoid unnecessary copy of fileName.
first you should check that weather the file is opened or not. for example if you dont have permission to access the file or if you are opening a file in write mode when there is no enough disk space, etc...
so
ifstream inFile(fileName);
if( ! inFile )
return;
while(inFile >> currentWord)
and about your question, are you including the fstream?