7

I need to know if there exists a method in ifstream so I can get the name of the file tied to it.

For instance

void some_function(ifstream& fin) {
    // here I need get name of file
}

Is there a method in ifstream/ofstream that allows to get that?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
vlad4378
  • 803
  • 1
  • 9
  • 21
  • 1
    No, there is no method existing. – Bk_ Jun 28 '15 at 13:18
  • 2
    @anshabhi No reasons for upvoting either. This information can easily be researched from looking at the [reference documentation](http://en.cppreference.com/w/cpp/io/basic_fstream). – πάντα ῥεῖ Jun 28 '15 at 13:25
  • @πάνταῥεῖ You can use such documentation to prove the *existence* of a method, but not the *lack* of existence of a method. – Sam Estep Jun 28 '15 at 13:26
  • 1
    @RedRoboHood Huh? I'd consider that reference complete. – πάντα ῥεῖ Jun 28 '15 at 13:26
  • 1
    @πάνταῥεῖ See [this](https://en.wikipedia.org/wiki/Philosophic_burden_of_proof#Proving_a_negative). It's always possible that a confusingly-named method might exist whose description doesn't make its function clear. – Sam Estep Jun 28 '15 at 13:27
  • @πάνταῥεῖ if that's the case, half of the SO's questions must be down-voted. More than half of the questions here, can be easily "researched" on reference docs. – anshabhi Jun 28 '15 at 13:28
  • @anshabhi Well, I'm certainly casting more downvotes than upvotes for most of the questions I see upcoming in the c++ tag queue (very often because of exactly this reason). – πάντα ῥεῖ Jun 28 '15 at 13:30
  • 1
    I think the point it that many times you have some non-standrad way ("hack") to do things. for example, I needed to iterate std::queue before, yet the standard gives me no way of doing so. reading some stack overflow question gave me hack of doing so, that I wasn't be able just for the manuals. this question could have being easly googled, but ok.. – David Haim Jun 28 '15 at 13:32
  • 1
    In an ideal world, you don't have much code taking an `std::ifstream&` but a lot taking `std::istream&`. IOW, code that takes input from a stream should typically not care about the stream's concrete nature. You may later want to switch from files to another kind of input. This is classical example of something where OOP actually makes a lot of sense. – Christian Hackl Jun 28 '15 at 15:18
  • @ChristianHackl That was one of my 1st toughts about the question, that any code reading/writing should be independent of the actual source/sink `std::fstream`. was used to open The OP probably asks for an XY-problem. – πάντα ῥεῖ Jun 28 '15 at 15:26
  • Possible duplicate of [Getting filename (or path) from fstream](https://stackoverflow.com/questions/10773391/getting-filename-or-path-from-fstream) – phuclv Dec 17 '18 at 09:46

3 Answers3

5

No. C++ streams do not save the name or the path of the file. but, since you need some string to initialize the stream anyway, you can just save it for future use.

David Haim
  • 25,446
  • 3
  • 44
  • 78
5

As mentioned there's no such method provided by std::fstream and it's derivates. Also std::basic_filebuf doesn't provide such feature.

For simplification I'm using std::fstream instead of std::ifstream/std::ofstream in the following code samples


I would recommend, to manage the underlying file name in a little helper class yourself:

class MyFstream {
public:
    MyFstream(const std::string& filename) 
    : filename_(filename), fs_(filename) {
    }

    std::fstream& fs() { return fs_; }
    const std::string& filename() const { return filename_; }
private:
    std::string filename_;
    std::fstream fs_;
};

void some_function(MyFstream& fin) {
    // here I need get name of file
    std::string filename = fin.filename();
}

int main() {
    MyFstream fs("MyTextFile.txt");
    some_function(fs):
}

Another alternative,- if you can't use another class to pass to some_function() as mentioned above -, may be to use an associative map of fstream* pointers and their associated filenames:

class FileMgr {         
public:
     std::unique_ptr<std::fstream> createFstream(const std::string& filename) {
          std::unique_ptr<std::fstream> newStream(new std::fstream(filename));
          fstreamToFilenameMap[newStream.get()] = filename;
          return newStream;
     }
     std::string getFilename(std::fstream* fs) const {
         FstreamToFilenameMap::const_iterator found = 
              fstreamToFilenameMap.find(fs);
         if(found != fstreamToFilenameMap.end()) {
             return (*found).second;
         }
         return "";
     }
private:
     typedef std::map<std::fstream*,std::string> FstreamToFilenameMap;

     FstreamToFilenameMap fstreamToFilenameMap;
};

FileMgr fileMgr; // Global instance or singleton

void some_function(std::fstream& fin) {
     std::string filename = fileMgr.getFilename(&fin);
}

int main() {
    std::unique_ptr<std::fstream> fs = fileMgr.createFstream("MyFile.txt");

    some_function(*(fs.get()));
}
Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • I like your second idea in spirit (although there are quite a few typos in the code, and the `return ""` for the reference return type is very ungood :)). However, I'm afraid it won't work in the face of moving. Consider: `std::unique_ptr fs = fileMgr.createFstream("MyFile.txt"); std::fstream other = std::move(*(fs.get())); some_function(other);`. The mapping will no longer hold and `""` will incorrectly be returned. – Christian Hackl Jun 28 '15 at 15:40
  • Done. But I cannot think of a good solution for the move problem. – Christian Hackl Jun 28 '15 at 15:59
0

No, such a method does not exist.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Sam Estep
  • 12,974
  • 2
  • 37
  • 75