1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
| #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <limits.h>
int main() { char buffer[PATH_MAX]; char *result; printf("=== Getcwd函数示例 ===\n"); // 示例1: 基本的获取当前目录操作 printf("\n示例1: 基本的获取当前目录操作\n"); // 方法1: 使用预分配的缓冲区 result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { printf("当前工作目录: %s\n", buffer); } else { perror("获取当前目录失败"); } // 方法2: 让系统分配内存(buf为NULL,size为0) char *dynamic_buffer = getcwd(NULL, 0); if (dynamic_buffer != NULL) { printf("动态分配的当前目录: %s\n", dynamic_buffer); free(dynamic_buffer); // 需要手动释放内存 } else { perror("动态获取当前目录失败"); } // 示例2: 缓冲区大小处理 printf("\n示例2: 缓冲区大小处理\n"); // 测试不同大小的缓冲区 size_t sizes[] = {10, 50, 100, PATH_MAX}; for (int i = 0; i < 4; i++) { char small_buffer[1000]; // 足够大的缓冲区 printf("尝试使用大小为 %zu 的缓冲区: ", sizes[i]); result = getcwd(small_buffer, sizes[i]); if (result != NULL) { printf("成功,目录长度: %zu 字节\n", strlen(small_buffer)); } else { if (errno == ERANGE) { printf("失败 - 缓冲区太小\n"); } else { printf("失败 - %s\n", strerror(errno)); } } } // 示例3: 创建测试目录并切换 printf("\n示例3: 目录切换演示\n"); // 保存原始目录 char original_dir[PATH_MAX]; if (getcwd(original_dir, sizeof(original_dir)) == NULL) { perror("保存原始目录失败"); exit(EXIT_FAILURE); } printf("原始目录: %s\n", original_dir); // 创建测试目录 const char *test_dir = "test_getcwd_dir"; if (mkdir(test_dir, 0755) == -1 && errno != EEXIST) { perror("创建测试目录失败"); } else { printf("创建测试目录: %s\n", test_dir); // 切换到测试目录 if (chdir(test_dir) == -1) { perror("切换目录失败"); } else { printf("切换到测试目录\n"); // 获取当前目录 result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { printf("切换后当前目录: %s\n", buffer); // 验证是否正确切换 if (strstr(buffer, test_dir) != NULL) { printf("目录切换验证成功\n"); } } // 在测试目录中创建子目录 const char *sub_dir = "sub_directory"; if (mkdir(sub_dir, 0755) == -1 && errno != EEXIST) { perror("创建子目录失败"); } else { printf("创建子目录: %s\n", sub_dir); // 切换到子目录 if (chdir(sub_dir) == -1) { perror("切换到子目录失败"); } else { printf("切换到子目录\n"); result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { printf("子目录路径: %s\n", buffer); } } } } // 返回原始目录 if (chdir(original_dir) == -1) { perror("返回原始目录失败"); } else { printf("返回原始目录\n"); result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { printf("确认当前目录: %s\n", buffer); } } } // 示例4: 错误处理演示 printf("\n示例4: 错误处理演示\n"); // 测试缓冲区太小的情况 char tiny_buffer[5]; result = getcwd(tiny_buffer, sizeof(tiny_buffer)); if (result == NULL) { if (errno == ERANGE) { printf("缓冲区太小错误处理正确: %s\n", strerror(errno)); } else { printf("其他错误: %s\n", strerror(errno)); } } // 测试无效参数 result = getcwd(buffer, 0); if (result == NULL) { if (errno == EINVAL) { printf("无效参数处理正确: %s\n", strerror(errno)); } } // 示例5: 实际应用场景 printf("\n示例5: 实际应用场景\n"); // 场景1: 程序配置文件定位 printf("场景1: 程序配置文件定位\n"); result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { char config_path[PATH_MAX * 2]; snprintf(config_path, sizeof(config_path), "%s/.myapp/config", buffer); printf("配置文件路径: %s\n", config_path); // 检查配置文件是否存在 if (access(config_path, F_OK) == 0) { printf("配置文件存在\n"); } else { printf("配置文件不存在,将创建默认配置\n"); } } // 场景2: 相对路径转换为绝对路径 printf("场景2: 相对路径处理\n"); const char *relative_paths[] = {"./file.txt", "../parent_dir", "subdir/file"}; for (int i = 0; i < 3; i++) { result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { char absolute_path[PATH_MAX * 2]; snprintf(absolute_path, sizeof(absolute_path), "%s/%s", buffer, relative_paths[i]); printf(" %s -> %s\n", relative_paths[i], absolute_path); } } // 场景3: 目录操作安全检查 printf("场景3: 目录操作安全检查\n"); char current_dir[PATH_MAX]; char previous_dir[PATH_MAX]; // 保存当前目录 if (getcwd(current_dir, sizeof(current_dir)) != NULL) { printf("当前工作目录: %s\n", current_dir); // 执行一些目录操作 // ... 目录操作代码 ... // 检查目录是否发生变化 if (getcwd(previous_dir, sizeof(previous_dir)) != NULL) { if (strcmp(current_dir, previous_dir) != 0) { printf("警告: 工作目录已改变\n"); printf("原目录: %s\n", current_dir); printf("现目录: %s\n", previous_dir); } else { printf("工作目录保持不变\n"); } } } // 场景4: 日志记录中的目录信息 printf("场景4: 日志记录\n"); time_t current_time = time(NULL); result = getcwd(buffer, sizeof(buffer)); if (result != NULL) { printf("[%s] INFO: 程序在目录 '%s' 中启动\n", ctime(¤t_time), buffer); } // 示例6: 跨平台兼容性考虑 printf("\n示例6: 跨平台兼容性\n"); // 获取系统路径限制 long path_max = pathconf(".", _PC_PATH_MAX); if (path_max == -1) { path_max = PATH_MAX; printf("使用默认PATH_MAX: %ld\n", path_max); } else { printf("系统PATH_MAX: %ld\n", path_max); } // 使用动态分配确保足够空间 char *safe_buffer = getcwd(NULL, 0); if (safe_buffer != NULL) { printf("动态分配确保安全: %s\n", safe_buffer); printf("路径长度: %zu 字节\n", strlen(safe_buffer)); free(safe_buffer); } // 示例7: 性能对比测试 printf("\n示例7: 性能对比测试\n"); // 测试预分配缓冲区的性能 clock_t start = clock(); for (int i = 0; i < 10000; i++) { getcwd(buffer, sizeof(buffer)); } clock_t preallocated_time = clock() - start; // 测试动态分配的性能 start = clock(); for (int i = 0; i < 10000; i++) { char *temp = getcwd(NULL, 0); if (temp != NULL) { free(temp); } } clock_t dynamic_time = clock() - start; printf("预分配缓冲区 10000 次调用耗时: %f 秒\n", ((double)preallocated_time) / CLOCKS_PER_SEC); printf("动态分配 10000 次调用耗时: %f 秒\n", ((double)dynamic_time) / CLOCKS_PER_SEC); printf("预分配方式通常更快\n"); // 清理测试目录 printf("\n清理测试资源...\n"); if (access(test_dir, F_OK) == 0) { if (rmdir(test_dir) == -1) { printf("删除测试目录失败: %s\n", strerror(errno)); } else { printf("删除测试目录完成\n"); } } return 0; }
|