10.4 Directories, Encoding, and File Management
Many file bugs come from the "around the file" details: the path is not where you think, the parent folder does not exist, the encoding is different, or a file-management operation overwrites important data.
Relative Paths and the Current Working Directory
A relative path is not automatically relative to the C++ source file. It is relative to the current working directory, usually the directory where you run the program.
std::filesystem::path path = std::filesystem::path("data") / "quotes.txt";
std::ifstream input(path);If the current working directory is the project root, C++ looks for:
project/
data/
quotes.txtBut if you run the program from another directory, the same relative path may not be found.
std::filesystem::current_path() to inspect the current working directory.Creating Directories
Writing reports/summary.txt fails if reports does not exist. Create parent directories first.
#include <filesystem>
#include <fstream>
int main() {
std::filesystem::path folder = "reports";
std::filesystem::create_directories(folder);
std::filesystem::path report = folder / "summary.txt";
std::ofstream output(report);
output << "Report ready\n";
return 0;
}create_directories() creates missing parent directories too, and it does nothing if the directory already exists.
UTF-8 Encoding
Text files store bytes. Encoding converts between characters and bytes. UTF-8 is one of the most common and compatible text encodings.
std::ofstream output("note.txt");
output << "Hello, C++!\n";The standard std::ifstream and std::ofstream examples here treat text as bytes. If your source file and terminal use UTF-8, writing UTF-8 text through streams is usually straightforward. If systems disagree about encoding, plain English may appear fine, but non-English text and symbols can break. Use UTF-8 consistently in course examples unless you have a specific reason not to.
Listing, Copying, Moving, and Deleting
std::filesystem can inspect and manage files:
std::filesystem::path path = "note.txt";
std::cout << std::filesystem::exists(path) << std::endl;
std::cout << std::filesystem::file_size(path) << std::endl;
std::cout << std::filesystem::is_regular_file(path) << std::endl;Directory listing uses std::filesystem::directory_iterator.
for (const auto& entry : std::filesystem::directory_iterator("reports")) {
std::cout << entry.path() << std::endl;
}Common management functions:
std::filesystem::copy_file(source, target): copy a file.std::filesystem::rename(source, target): move or rename a file.std::filesystem::remove(path): delete a file or empty directory.std::filesystem::remove_all(path): delete a directory tree.
These operations can overwrite, fail, or remove data. Treat them with care.