Detect if a file exists?

Jul 10, 2017 at 6:28pm
Is there a way to simply do this?

Edit: Also looking for a way to detect what the extension is.

Edit 2: It turns out I don't need a way to detect what the extension is.
Last edited on Jul 10, 2017 at 11:20pm
Jul 10, 2017 at 8:11pm
Yes. Try to open the file, and check the errors. Windows gui code has tools to search for a file built in. Unix has tools to do this as well, but I don't know if its better to link in a library or to just ask the OS on unix.

The extension ... is part of the file name you used... if you do not know it, and used a wildcard search, the results of the search will give the name and therefore its extension.

Jul 10, 2017 at 8:13pm
Under Windows you can use the FindFirstFile function. To get the extension of the file take all the characters after the last colon.
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>
#include <string>

bool FileExists(const std::string& filename)
{
  WIN32_FIND_DATAA fd = {0};
  HANDLE hFound = FindFirstFileA(filename.c_str(), &fd);
  bool retval = hFound != INVALID_HANDLE_VALUE;
  FindClose(hFound);

  return retval;  
}

https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx
Jul 10, 2017 at 11:13pm
I'm trying to make my program OS-independent. It also turns out that I don't need extension handling.

Edit: I'm blind apparently. Your solution @jonnin appears to be a good one - gonna try it now.
Last edited on Jul 11, 2017 at 12:06am
Jul 15, 2017 at 12:59pm
If a file couldn't be opened because it didn't exist or whatever...

1
2
3
4
5
6
7
8
#include <iostream>
#include <fstream>

int main()
{
    if (std::fstream{FILE_NAME}) std::cout << "file exists\n";
    else std::cerr << "file couldn\'t be opened (not existing or failed to open)\n";
}

File extension

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main()
{
    const std::string file_name{"main.cpp"};
    if (file_name.find('.') == std::string::npos) std::cout << "no file extension\n";
    else if (file_name.find_last_of('.') == file_name.length() - 1) std::cout << ".\n";
    else std::cout << file_name.substr(file_name.find_last_of('.') + 1) << '\n';
}
Last edited on Jul 17, 2017 at 1:21pm
Jul 15, 2017 at 1:47pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <iomanip>

// http://en.cppreference.com/w/cpp/experimental/fs
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem ;

// see: http://www.boost.org/doc/libs/1_63_0/libs/filesystem/doc/index.htm
// #include <boost/filesystem.hpp>
// namespace fs = boost::filesystem ;

int main()
{
    const fs::path this_file = __FILE__ ;
    std::cout << "path: " << this_file << '\n' 
              << "parent: " << this_file.parent_path() << '\n' 
              << "exists? " << std::boolalpha << fs::exists(this_file) << '\n' // true
              << "extension: " << std::quoted( this_file.extension().string() ) << '\n' ; // ".cpp"
}

http://rextester.com/IAUIW87887
http://rextester.com/MTSV94763
Jul 17, 2017 at 1:05pm
@JLBorges Too bad not everyone has access to this library (filesystem). It would simplify file handling a lot. Boost has it, but you need to link a shared library.
Jul 17, 2017 at 1:17pm
Everyone would have it (reasonably soon enough).
This TS has now been incorporated into the standard. (C++17).
Jul 17, 2017 at 1:25pm
@JLBorges Is C++17 officially out yet? I think it's soon this year if it's not out yet.

Wikipedia wrote:
is not expected to undergo any major changes before publication of the final standard later in the year
https://en.wikipedia.org/wiki/C%2B%2B17
Last edited on Jul 17, 2017 at 1:28pm
Jul 17, 2017 at 1:35pm
No, it is in its final ISO balloting stage (voting by national standards bodies).

The July meeting of the ISO C++ committee was the first meeting for C++20 - they are already done with C++17.
Jul 18, 2017 at 1:29pm
If your environment has stat(), then you can use that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <sys/stat.h>
#include <errno.h>
#include <cstring>
int main()
{
    struct stat st;
    if (stat("myfile", &st) == 0) {
        std::cout << "myfile exists\n";
    } else {
        std::cout << "Can't stat myfile: errno=" << errno << ": "
             << strerror(errno) << '\n';
    }
}

If the files doesn't exist (as opposed to some other error), then stat will return non-zero and set errno to ENOENT.

Just because the file exists doesn't imply that you can open it.

Jul 19, 2017 at 8:46am
For now the best would be to use boost or Kahless_9.
Topic archived. No new replies allowed.