C语言逐字符拷贝字符串构建目录路径时仅获取最后一个字符的问题咨询
问题分析与解决方案
首先,你的代码里有两个核心错误,直接导致了只能获取到单个字符而非完整路径:
1. 未正确递增path的索引变量j
你把name[i]赋值给path[j]后,没有执行j++操作,导致每次新字符都会覆盖path[0]的位置——相当于每次都在同一个位置写新字符,自然只能看到最后一次写入的内容。
2. 字符串结束符'\0'的位置设置错误
你用name数组的索引i来计算path的结束符位置,但i和path的实际长度(由j追踪)并不匹配。比如当遍历到name的第3个字符时,path其实只写入了1个字符(因为j没递增),这时候设置path[i+1] = '\0'完全不符合逻辑。正确的做法应该是用j来定位path的结束符位置。
另外,遇到'/'时,你写的path[i] = '\0'也是错误的,同样应该用path[j] = '\0',因为j才是path当前最后一个字符的下一个位置。
修正后的代码
下面是修复了上述问题的完整代码:
int i, j = 0; char name[256] = "dir2/dir3/a"; // 示例路径 char path[256] = {0}; for (i = 0; i < strlen(name); i++) { if (name[i] != '/') { path[j] = name[i]; j++; path[j] = '\0'; // 每次写入字符后立即设置结束符,保证是合法字符串 printf("path%d: %s\n", i, path); } else { path[j] = '\0'; // 用j定位结束符,而非i printf("path: %s\n", path); int n = chdir(path); if (n == -1) { // chdir返回-1时才检查具体错误码 if (errno == ENOENT) { n = mkdir(path, 0777); if (n != 0) { fprintf(stderr, "Failed to make the directory to extract: %s\n", strerror(errno)); close(fmypack); return E_DIR1; } // 创建成功后切换目录,也要检查错误 if (chdir(path) != 0) { fprintf(stderr, "Failed to enter new directory: %s\n", strerror(errno)); close(fmypack); return E_DIR1; } } else if (errno == EACCES) { fprintf(stderr, "Failed to access the directory: %s, %s\n", path, strerror(errno)); close(fmypack); return E_DIR2; } else { fprintf(stderr, "Unknown error when trying to access the directory: %s, %s\n", path, strerror(errno)); close(fmypack); return E_DESCO; } } memset(path, 0, sizeof(path)); j = 0; } } // 处理路径最后一段(如果路径不以/结尾的话) if (j > 0) { path[j] = '\0'; // 可根据需求添加逻辑:比如如果是目录就创建/切换,是文件则跳过 }
更高效的实现方式
你当前的方案依赖频繁切换目录,其实可以不用chdir,直接构建完整路径段,这样更安全也更高效(避免目录切换的上下文开销)。这里提供两种优化思路:
思路1:用strtok分割路径(代码更简洁)
char path[256] = {0}; char *token = strtok(name, "/"); strcpy(path, "."); // 初始路径设为当前目录 while (token != NULL) { strcat(path, "/"); strcat(path, token); struct stat st; if (stat(path, &st) != 0) { if (errno == ENOENT) { if (mkdir(path, 0777) != 0) { fprintf(stderr, "Failed to create directory: %s\n", strerror(errno)); close(fmypack); return E_DIR1; } } else { fprintf(stderr, "Failed to stat directory: %s\n", strerror(errno)); close(fmypack); return E_DIR2; } } else if (!S_ISDIR(st.st_mode)) { fprintf(stderr, "%s is not a directory\n", path); close(fmypack); return E_DIR2; } token = strtok(NULL, "/"); }
思路2:手动递归创建多级目录
如果需要支持类似mkdir -p的多级目录创建,可以自己实现递归逻辑,无需依赖外部工具,兼容性更强。
内容的提问来源于stack exchange,提问作者JamesR
相关产品推荐
相关产品推荐

