Reputation: 584
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
Upvotes: 3
Views: 1946
Reputation: 48635
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;
}
Upvotes: 2
Reputation: 11406
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());
}
Upvotes: 2
Reputation: 28289
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 might be possible to use _popen
and fgets
instead of redirecting to file.
Upvotes: -3