如何编写可跨Windows和Linux平台的C++目录创建程序?
Hey there! I’ve run into this exact cross-platform directory creation headache before—nothing’s more frustrating than writing code that works on Windows only to have it break on Linux. Let’s walk through the most reliable solutions for your C++ program that’ll run smoothly on both Windows 10 and Linux.
方案1:使用C++17标准库(强烈推荐)
Starting with C++17, the <filesystem> library became part of the standard, which means it’s natively supported by modern compilers on both platforms—no extra dependencies needed. It handles all the platform-specific quirks under the hood, so you write clean, portable code.
Here’s a complete example that covers both single and nested directory creation, plus error handling:
#include <filesystem> #include <iostream> namespace fs = std::filesystem; // 别名简化代码 int main() { // 创建单个目录 try { if (fs::create_directory("my_single_dir")) { std::cout << "Single directory created successfully!\n"; } else { std::cout << "Single directory already exists.\n"; } // 递归创建多级目录(比如parent/child/grandchild) if (fs::create_directories("parent/child/grandchild")) { std::cout << "Nested directories created successfully!\n"; } else { std::cout << "Nested directories already exist.\n"; } } catch (const fs::filesystem_error& e) { std::cerr << "Error occurred: " << e.what() << '\n'; } return 0; }
编译注意事项
- Linux: If you’re using GCC 8+, compile with:
For Clang 6+, use:g++ your_file.cpp -std=c++17 -lstdc++fs -o directory_creatorclang++ your_file.cpp -std=c++17 -lc++fs -o directory_creator - Windows: With Visual Studio 2017 or later, just set your project to use C++17 (it’s enabled by default in newer versions) and compile normally—no extra flags needed.
方案2:使用Boost.Filesystem(兼容旧C++标准)
If your project can’t use C17 (e.g., stuck on C11/C++14), Boost.Filesystem is the tried-and-true cross-platform alternative. It’s been around for years and provides almost identical functionality to the standard <filesystem> library.
First, you’ll need to install the Boost libraries (they’re available via package managers on Linux, or you can download them for Windows). Here’s the code:
#include <boost/filesystem.hpp> #include <iostream> namespace fs = boost::filesystem; int main() { try { // 创建单个目录 if (fs::create_directory("boost_single_dir")) { std::cout << "Single directory (Boost) created successfully!\n"; } // 递归创建多级目录 if (fs::create_directories("boost_parent/boost_child")) { std::cout << "Nested directories (Boost) created successfully!\n"; } } catch (const fs::filesystem_error& e) { std::cerr << "Boost Error: " << e.what() << '\n'; } return 0; }
编译注意事项
- Linux: Compile with the Boost filesystem library linked:
g++ your_file.cpp -lboost_filesystem -o directory_creator_boost - Windows: Configure your IDE to include Boost’s header directory and link against
boost_filesystem.lib(orboost_filesystem-vcXXX-mt.libdepending on your Visual Studio version).
方案3:条件编译调用原生API(不推荐,除非绝对必要)
If you can’t use the standard library or Boost, you can directly call the platform-specific APIs using preprocessor directives. This approach works, but it’s more verbose and requires maintaining two separate code paths—easy to introduce bugs.
Here’s how to do it:
#include <iostream> #include <string> #include <vector> #include <sstream> #ifdef _WIN32 #include <windows.h> #else #include <sys/stat.h> #include <sys/types.h> #include <errno.h> #include <cstring> // Linux下递归创建目录的辅助函数 bool create_recursive_dir(const std::string& path) { size_t pos = 0; std::string current_path; while (pos != std::string::npos) { pos = path.find('/', pos + 1); current_path = path.substr(0, pos); if (mkdir(current_path.c_str(), 0755) != 0) { if (errno != EEXIST) return false; } } return true; } #endif int main() { const std::string single_dir = "native_single_dir"; const std::string nested_dir = "native_parent/native_child"; #ifdef _WIN32 // Windows创建单个目录 if (CreateDirectoryA(single_dir.c_str(), NULL)) { std::cout << "Single directory (Win Native) created!\n"; } else if (GetLastError() == ERROR_ALREADY_EXISTS) { std::cout << "Single directory (Win Native) already exists.\n"; } else { std::cerr << "Win Error: Failed to create single directory.\n"; } // Windows递归创建多级目录(手动拆分路径) std::string current_win_path; std::stringstream ss(nested_dir); std::string part; while (std::getline(ss, part, '/')) { current_win_path += part + "\\"; if (!CreateDirectoryA(current_win_path.c_str(), NULL) && GetLastError() != ERROR_ALREADY_EXISTS) { std::cerr << "Win Error: Failed to create " << current_win_path << '\n'; return 1; } } std::cout << "Nested directories (Win Native) created!\n"; #else // Linux创建单个目录 if (mkdir(single_dir.c_str(), 0755) == 0) { std::cout << "Single directory (Linux Native) created!\n"; } else if (errno == EEXIST) { std::cout << "Single directory (Linux Native) already exists.\n"; } else { std::cerr << "Linux Error: " << strerror(errno) << '\n'; } // Linux递归创建多级目录 if (create_recursive_dir(nested_dir)) { std::cout << "Nested directories (Linux Native) created!\n"; } else { std::cerr << "Linux Error: " << strerror(errno) << '\n'; } #endif return 0; }
Final Recommendation
Stick with the C17 <filesystem> library if at all possible—it’s standard, clean, and avoids external dependencies. If you’re stuck on an older C standard, Boost.Filesystem is the next best bet. Only use the native API approach if you have strict constraints that prevent using the other two options.
内容的提问来源于stack exchange,提问作者K.Mahan

