For this project I have to open a file with an ifstream in one function. The code i have written can be seen below:
bool FileReader::openFile(std::string fileName) {
std::ifstream inFile;
streams.push_back(std::move(inFile));
if (streams.back().is_open()) {
std::cout << "File Found";
return true;
}
else {
std::cout << "File Not Found";
return false;
}
and then close it in another function. Here is that empty function:
bool FileReader::closeFile(std::string fileName) {
return false;
}
Both of these functions work by passing in the file path as a parameter and the ifstreams are stored in a global vector so multiple files can be open at once
What I dont understand is how i can close one of those streams with just the filename as a paramater.
Any help would be greatly appreciated
CodePudding user response:
There is no direct and portable way to get the file name of a std::ifstream. You can use a map instead of a vector, to reference streams with their filename.
Example using std::unordered_map<>:
#include <fstream>
#include <string>
#include <unordered_map>
class FileReader
{
// ...
std::unordered_map<std::string, std::ifstream> streams_;
// ...
// attempts to open fie fileName, and adds it to map of streams.
//
// returns:
// - true on success
// - false if file is already opened or could not be opened.
//
bool openFile(const std::string& fileName)
{
if (streams_.find(fileName) != streams_.end())
return false;
auto ifs = std::ifstream{fileName};
if (!ifs.is_open())
return false;
streams_.emplace(fileName, std::move(ifs));
return true;
}
bool closeFile(const std::string& fileName)
{
auto pos = streams_.find(fileName);
if (pos == streams_.end())
return false;
streams_.erase(pos);
return true;
}
};
Note that, unlike your example, the variable containing the streams is in a scope that is visible to both openFile() and closeFile().
CodePudding user response:
There is no direct way to get the name of a std::fstream.. You can use a map instead of a vector, to reference streams with their filename.
Example using std::unordered_map<>:
#include <fstream>
#include <string>
#include <unordered_map>
class FileReader
{
// ...
std::unordered_map<std::string, std::ifstream> streams_;
// ...
// attempts to open fie fileName, and adds it to map of streams.
//
// returns:
// - true on success
// - false if file is already opened or could not be opened.
//
bool openFile(const std::string& fileName)
{
if (streams_.find(fileName) != streams_.end())
return false;
auto ifs = std::ifstream{fileName};
if (!ifs.is_open())
return false;
streams_.emplace(fileName, std::move(ifs));
return true;
}
bool closeFile(const std::string& fileName)
{
if (auto pos = streams_.find(fileName); pos != streams_.end())
{
streams_.erase(pos);
return true;
}
return false;
}
};
Note that, unlike your example, the variable containing the streams is in a scope that is visible to both openFile() and closeFile().