3

I'm trying to code a program where it opens and reads a file automatically. But the problem is the file is stored in a folder which name is unknown. I only know where the folder is located and the file's name. How to get to that file's path in char* ?

Edit: example: d:\files\<random folder>\data.txt

I don't know the name of random folder but I know that it exists in d:\files

13
  • Do you know how to list all folders in d:\files? Commented Jan 6, 2016 at 15:54
  • 2
    What happens when two directories have the same file? Commented Jan 6, 2016 at 15:56
  • 1
    There is currently no C++ way to iterate over files in a given directory (which is, of course, a shame and terrible legacy). You'd have to use third-party lib like boost. Commented Jan 6, 2016 at 15:56
  • Let's assume whomever made the files folder made sure that there was no file having the same names in different folders. Commented Jan 6, 2016 at 16:04
  • 4
    I highly reccommed using / as your directory separator. The '\' is an escape character and some are control characters such as \t, \f, and \b (tab, formfeed and backspace). Commented Jan 6, 2016 at 16:09

3 Answers 3

2

Since this is tagged windows, you might as well use the Windows API functions:

to enumerate and loop through all the files in a given directory.

To check for a directory, look at dwFileAttributes contained in the WIN32_FIND_DATA structure (filled by the calls to Find...File()). But make sure to skip . and .. directories. If needed, this can be done recursively.

You can check the links for some examples, or see Listing the Files in a Directory.

In case you are using MFC, you can use CFileFind (which is a wrapper around the API functions):

CFileFind finder;
BOOL bWorking = finder.FindFile(_T("*.*"));
while (bWorking)
{
   bWorking = finder.FindNextFile();
   TRACE(_T("%s\n"), (LPCTSTR)finder.GetFileName());
}
Sign up to request clarification or add additional context in comments.

Comments

2

Just for fun, I implemented this using the new, experimental <filesystem> FS Technical Specification supported by GCC 5.

#include <iostream>
#include <experimental/filesystem>

// for readability
namespace fs = std::experimental::filesystem;

int main(int, char* argv[])
{
    if(!argv[1])
    {
        std::cerr << "require 2 parameters, search directory and filename\n";
        return EXIT_FAILURE;
    }

    fs::path search_dir = argv[1];

    if(!fs::is_directory(search_dir))
    {
        std::cerr << "First parameter must be a directory: " << search_dir << '\n';
        return EXIT_FAILURE;
    }

    if(!argv[2])
    {
        std::cerr << "Expected filename to search for\n";
        return EXIT_FAILURE;
    }

    // file to search for
    fs::path file_name = argv[2];

    const fs::directory_iterator dir_end; // directory end sentinel

    // used to iterate through each subdirectory of search_dir
    fs::directory_iterator dir_iter(search_dir);

    for(; dir_iter != dir_end; ++dir_iter)
    {
        // skip non directories
        if(!fs::is_directory(dir_iter->path()))
            continue;

        // check directory for file

        // iterate through files in this subdirectory dir_iter->path()
        auto file_iter = fs::directory_iterator(dir_iter->path());

        for(; file_iter != dir_end; ++file_iter)
        {
            // ignore directories and wrong filenames
            if(fs::is_directory(file_iter->path())
            || file_iter->path().filename() != file_name)
                continue;

            // Ok we found it (the first one)
            std::cout << "path: " << file_iter->path().string() << '\n';
            return EXIT_SUCCESS;
        }
    }

    // Not found
    std::cout << file_name << " was not found in " << search_dir.string() << '\n';

    return EXIT_FAILURE;
}

Comments

-3

The idea is: list the directories under d:\files and try to open the file in each directory.

There isn't (yet) a standard C++ way of getting all the existing files/directories. A crude but easy way of doing this would be

system("dir d:\\files /b /ad > tmpfile");

This lists all directories (/ad), redirected to a temporary file. Then open the file:

std::ifstream list("tmpfile");

And read it:

std::string dirname;
std::string filename;
while (std::getline(list, dirname))
{
    filename = "d:\\files\\" + dirname + "\\data.txt";
    if ( ... file exists ... )
        break;
}

I call this method crude because it has problems that are hard/impossible to fix:

  • It overwrites a potentially useful file
  • It doesn't work if current directory is read-only
  • It will only work in Windows

It might be possible to use _popen and fgets instead of redirecting to file.

2 Comments

can i store the file in some other directory? in case that folder is read-only
Yes. Also, if you use _popen, there is no need for a temp-file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.