拼接文件名并打开文件:切换目录后验证文件存在失败问题
问题分析与修复方案
核心问题
你的代码存在三个关键问题,导致文件判断逻辑失效:
- 字符串未终止:
char app[4] = ".txt";仅分配4字节数组,但字符串字面量.txt实际需要5字节(包含终止符\0),导致app不是合法C字符串,strncat会读取内存垃圾数据,拼接出错误文件名。 - 缓冲区溢出:
char k[10];空间不足,int最大值转字符串是10位(如2147483647),加上.txt和终止符需要15字节,10字节缓冲区会溢出破坏内存。 - 错误信息模糊:open失败时仅打印固定提示,无法区分是文件不存在、权限不足还是其他问题,不利于调试。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> int check_file_exists(int key) { // 扩大缓冲区,足够容纳int最大值+".txt"+终止符 char k[20]; // 自动分配空间,确保包含字符串终止符 char app[] = ".txt"; int status; // 切换工作目录 if(chdir("txtFiles") == -1){ perror("Error while changing directories."); return -1; } // 转换key为字符串,用sizeof(k)确保缓冲区安全 snprintf(k, sizeof(k), "%d", key); // 追加.txt后缀,strcat更简洁安全 strcat(k, app); printf("Checking file: %s\n", k); // 尝试打开文件 if((status = open(k, O_RDONLY)) == -1){ // 打印具体错误原因 perror("Failed to open file"); printf("File DOESNT exist or cannot be accessed.\n"); } else { printf("File exists.\n"); // 关闭文件,避免资源泄漏 close(status); } return 0; }
关键修改点
- 把
char app[4] = ".txt";改为char app[] = ".txt";,让编译器自动分配包含终止符的空间。 - 扩容
k的缓冲区到20字节,避免溢出。 - 用
strcat(k, app)替代strncat(k, app, 4),简化逻辑且避免读取垃圾数据。 - open失败时调用
perror打印具体错误,方便排查问题。 - 添加
close(status),修复打开文件后未关闭的资源泄漏问题。
内容的提问来源于stack exchange,提问作者ICS
相关产品推荐
相关产品推荐

