C++ createFolder函数创建长名文件夹出现乱码后缀问题求助
问题原因
你的问题根源完全出在char buffer[]及后续的字符串处理逻辑上,具体问题点如下:
- 缓冲区大小计算错误:
sizeof(dir)和sizeof(foldername)获取的是指针的字节数(比如64位系统下为8字节),并非字符串实际长度。这导致定义的buffer大小完全不符合路径拼接的需求,当文件夹名称较长时,缓冲区无法容纳完整路径+终止符,后续操作会读取栈上的垃圾数据。 - 字符串拼接逻辑错误:连续两次调用
strncpy时,第二次直接将foldername覆盖到buffer起始位置,根本没实现dir与foldername的拼接。且strncpy不会自动添加字符串终止符'\0',当源字符串长度等于缓冲区大小时,buffer会成为无终止符的非法字符串,mkdir读取时会越界读取栈内存中的随机数据,也就是你看到的乱码后缀。
解决办法
推荐两种修复方式,优先选择更安全的C++字符串处理方案:
方式一:使用std::string(最安全,避免手动内存管理)
#include <string> #include <sys/stat.h> #include <cstring> #include <iostream> // 假设hasFolder为已实现的函数 bool hasFolder(const char* dir, const char* foldername); void createFolder(const char *dir, const char *foldername) { // ! Checking to see if the folder already exists if (hasFolder(dir, foldername)) return; // ? Full directory std::string buffer(dir); // 确保路径末尾有分隔符 if (!buffer.empty() && buffer.back() != '/') { buffer += '/'; } buffer += foldername; // ? Creating folder int success = mkdir(buffer.c_str(), 0755); // 必须指定权限,避免权限异常 // ! Checking to see if folder creation worked if (success == -1) std::cerr << "Error: " << strerror(errno) << "\n"; } int main(int argc, char *argv[]) { // This will work fine createFolder("./", "123456"); // Now works correctly createFolder("./", "1234567"); return 0; }
方式二:手动管理C风格字符串(需注意内存安全)
如果坚持使用C风格字符串,需正确计算长度并处理终止符:
#include <sys/stat.h> #include <cstring> #include <iostream> #include <cstdlib> bool hasFolder(const char* dir, const char* foldername); void createFolder(const char *dir, const char *foldername) { if (hasFolder(dir, foldername)) return; size_t dir_len = strlen(dir); size_t name_len = strlen(foldername); // 计算缓冲区大小:dir长度 + 可选分隔符 + 名称长度 + 终止符 size_t buffer_size = dir_len + (dir_len > 0 && dir[dir_len-1] != '/' ? 1 : 0) + name_len + 1; char* buffer = static_cast<char*>(malloc(buffer_size)); if (!buffer) { std::cerr << "Error: Memory allocation failed\n"; return; } strcpy(buffer, dir); if (dir_len > 0 && buffer[dir_len-1] != '/') { strcat(buffer, "/"); } strcat(buffer, foldername); int success = mkdir(buffer, 0755); if (success == -1) std::cerr << "Error: " << strerror(errno) << "\n"; free(buffer); // 记得释放内存 }
额外注意点
- POSIX标准的
mkdir函数必须传入第二个参数指定文件夹权限(如0755),省略会继承进程umask导致权限异常。 - 始终确保C风格字符串以
'\0'终止,避免越界访问引发的未定义行为。
内容的提问来源于stack exchange,提问作者Keshav V.
相关产品推荐
相关产品推荐

