Hi!
HERE IS MY PROBLEM
==============
I'm interested in a function that opens for editing, then saves and closes in turn all the files in C:\DIRECTORY\
WHY THAT PROBLEM
=============
The C:\DIRECTORY\ contains text files *.txt whose content should undergo some changes (that pertains to ALL THE FILES IN C:\DIRECTORY\). So I should open each file, edit, save and then close it. Everything is clear to me when dealing with concrete files but I have no idea of how to go through the unknown list of files in C:\DIRECTORY\.
Thanks in advance for any hint!

Dani AI

Generated

Good suggestions from (Win32 enumeration) and the demo by — those work on Windows. For modern C++ code, prefer the standardized filesystem API (available since C++17): it gives a compact, portable way to iterate, filter and manipulate files instead of hand-rolling Win32 or compiler-specific calls. (en.cppreference.com)

A practical, minimal workflow: iterate the directory, skip non-regular files, load the file into a string, apply your edits, write to a temporary file in the same directory, then replace the original. Example (C++17+):

#include <filesystem>
#include <fstream>
#include <sstream>
namespace fs = std::filesystem;

for (const auto& e : fs::directory_iterator(R"(C:\DIRECTORY)")) {
    if (!e.is_regular_file()) continue;
    if (e.path().extension() != ".txt") continue;

    std::ostringstream inbuf;
    std::ifstream in(e.path(), std::ios::binary);
    inbuf << in.rdbuf();
    std::string content = inbuf.str();

    // perform edits on `content` here

    fs::path tmp = e.path();
    tmp += ".tmp";
    std::ofstream out(tmp, std::ios::binary);
    out << content;
    out.close();

    fs::rename(tmp, e.path()); // replace the file
}

directory_iterator is the right iterator for a single-directory pass (non-recursive). If you need recursion use recursive_directory_iterator. Note: older toolchains sometimes required extra linker flags for <filesystem> (e.g. -lstdc++fs or -lc++fs); check your compiler version if you hit unresolved symbols. (en.cppreference.com)

For safe replacement and atomicity: the common pattern is "write-to-temp then rename". The C++ rename/std::filesystem::rename follows POSIX-style semantics for replacement, but on Windows you can run into locking/atomicity edge cases — if you need guaranteed atomic replace with attribute/ACL preservation, call the Win32 ReplaceFile API on Windows. Catch and log filesystem_error and fall back when rename/replace fails. (en.cppreference.com)

If you must support old C++Builder/Borland code, the findfirst/findnext family in dir.h (or _wfindfirst/_wfindnext) is what you saw in older posts; for portability to pre-C++17 compilers consider Boost.Filesystem as a drop-in modern alternative. (docwiki.embarcadero.com)

Troubleshooting notes: skip read-only files or change permissions first, catch exceptions and continue (don’t abort on one bad file), be careful with encoding and CR/LF on Windows, and avoid renaming across volumes (temp file must live on the same volume). If strict atomic replacement is required on Windows and files may be in use, schedule work or use Windows-specific APIs.

Recommended Answers

All 5 Replies

The functions FindFirstFile() and FindNextFile() will iterate the all the files and sub-directories. For each file they return a structure that contains the filename, attributes, size and other data. Check the file's attributes to see that it is a normal file and, if it is, your program can open and edit it.

Thanks Ancient Dragon for your answer. As for FindFirstFile() and FindNextFile(), could you please tell me which C++ library should be included in order for the two functions to be available? I was not able to find them in C++ Builder but that doesn't mean they do not exist at all.
Thanks again!

Member Avatar for Member #46692

Thanks Ancient Dragon for your answer. As for FindFirstFile() and FindNextFile(), could you please tell me which C++ library should be included in order for the two functions to be available? I was not able to find them in C++ Builder but that doesn't mean they do not exist at all.
Thanks again!

Does it support <windows.h>

If not, dev-cpp from bloodshed definitely does.

#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
    HANDLE hFind;
    WIN32_FIND_DATA FindData;
    int ErrorCode;
    BOOL Continue = TRUE;

    cout << "A decent FindFirst/Next demo." << endl << endl;

    hFind = FindFirstFile("C:\\*.txt", &FindData);

    if(hFind == INVALID_HANDLE_VALUE)
    {
        ErrorCode = GetLastError();
        if (ErrorCode == ERROR_FILE_NOT_FOUND)
        {
            cout << "There are no files matching that path/mask\n" << endl;
        }
        else
        {
            cout << "FindFirstFile() returned error code " << ErrorCode << endl;
        }
        Continue = FALSE;
    }
    else
    {
        cout << FindData.cFileName << endl;
        
    }

    if (Continue)
    {
        while (FindNextFile(hFind, &FindData))
        {
            cout << FindData.cFileName << endl;
            
        }

        ErrorCode = GetLastError();

        if (ErrorCode == ERROR_NO_MORE_FILES)
        {
            cout << endl << "All files logged." << endl;
        }
        else
        {
            cout << "FindNextFile() returned error code " << ErrorCode << endl;
        }

        if (!FindClose(hFind))
        {
            ErrorCode = GetLastError();
            cout << "FindClose() returned error code " << ErrorCode << endl;
        }
    }

   
    cin.get();
}

Thanks Ancient Dragon for your answer. As for FindFirstFile() and FindNextFile(), could you please tell me which C++ library should be included in order for the two functions to be available? I was not able to find them in C++ Builder but that doesn't mean they do not exist at all.
Thanks again!

You will also need to read the Microsoft docs for those functions -- here

Thanks a lot friends! Both findfirst and findnext functions are introduced by dir.h (The Borland versions don't end with "File")

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.