With C++17, the filesystem library has been introduced. This makes live easier.
Now, we have an iterator, that iterates over all files in a directory using the directory_iterator. There is even a version available, that will iterate over all sub-directories.
So, then we will use this iterator to copy all directory entries into a std::vector
. Please note: the std::vector
has a so called range constructor (5). You give it a begin and an end iterator and it fills the std::vector
with all values given by the iterator. So, the line:
std::vector fileList(fs::directory_iterator(startPath), {});
will read all directory entries into the vector. The {} will be used as the default constructor, which is equal to the end iterator.
So, now we have all filenames. We will open all regular files in a loop and read the file completely into the memory. Note: For big files this may cause trouble!
Similar to the std::vector
, also the std::string
has a range constructor. And as iterator we will use the istreambuf
iterator. With that we will read all charachtes from the opened file. So, after
std::string fileContent(std::istreambuf_iterator<char>(fileStream), {});
the complete contents of the file will be in the std::string
variable "fileContent".
Then, we loop over the std::vector
with all lookup strings, and search the loop string in the "fileContent" string using std::search
.
If we could find the lookup string, then we show the filename and the lookup string on the screen.
By using modern C++ language elements and libraries, we can do the whole task with just a few lines of code:
#include <iostream>
#include <fstream>
#include <filesystem>
#include <vector>
#include <iterator>
#include <algorithm>
// Namespace alias for easier writing
namespace fs = std::filesystem;
// Some demo test path with files
const fs::path startPath{ "c:\\temp\\" };
// Some test strings that we are looking for
std::vector<std::string> lookUpStrings{ "Apple","Banana","Orange" };
int main() {
// Get all file names of the files in the specified directory into this vector
std::vector fileList(fs::directory_iterator(startPath), {});
// In a loop, open all files an search for lookup strings
for (const fs::directory_entry& de : fileList) {
// Open file and check, if it could be opened
if (fs::is_regular_file(de.path()))
if (std::ifstream fileStream{ de.path().string() }; fileStream) {
// Read complete file
std::string fileContent(std::istreambuf_iterator<char>(fileStream), {});
// Search for the lookup strings
for (const std::string& l : lookUpStrings)
if (std::search(fileContent.begin(), fileContent.end(), l.begin(), l.end()) != fileContent.end())
std::cout << "File '" << de.path().string() << "' contains '" << l << "'\n";
}
else std::cerr << "\*** Error: Could not open file '" << de.path().string() << "'\n";
}
return 0;
}