C语言文件存在性检查异常及BookId自增功能实现问题
解决C语言文件存在性检查失效&读取最后BookId自增的问题
兄弟,你遇到的问题根源太明确了:你在判断myFile == NULL之前,根本没初始化这个指针变量!局部指针变量默认是随机的垃圾值,不管文件删没删,这个判断都完全不可靠,这就是为啥删了文件还会进if分支的原因。
下面给你一步步梳理解决思路和修正后的代码:
1. 先搞定文件存在性检查的正确姿势
你不能直接用未初始化的指针判断,必须先尝试打开文件或者用系统函数检查:
方法一:用fopen只读模式验证(跨平台友好)
直接以"r"模式打开文件,如果返回NULL,说明文件不存在(或者权限问题,这里先默认是不存在);如果成功打开,说明文件存在。
方法二:用access函数(更直接的存在性检查)
Windows下是_access,Linux/macOS下是access,可以直接检查文件是否存在,不需要打开文件。
2. 完整实现逻辑(读取最后BookId并自增写入)
假设你的Book_Id是整数类型,下面是修正后的完整代码片段,包含必要的错误处理:
#include <stdio.h> #include <string.h> // 跨平台access函数适配 #ifdef _WIN32 #include <io.h> #define access _access #else #include <unistd.h> #endif #define NR_OF_BOOKS 3 // 示例数量,替换成你的实际值 int main() { // 先检查文件是否存在 if (access("file.txt", F_OK) != 0) { // 文件不存在:创建文件并写入列名 FILE *myFile = fopen("file.txt", "w"); if (myFile == NULL) { perror("Failed to create file"); return 1; } // 写入列名(用\t分隔,注意换行) fprintf(myFile, "%s\t%s\t%s\n", "Book_Id", "Record_Date", "Book_Name"); // 初始化第一个BookId为1,写入初始数据(如果需要) for (int x = 0; x < NR_OF_BOOKS; x++) { int newId = 1 + x; char recordDate[] = "2024-05-20"; // 替换成你的实际日期 char bookName[] = "Book Name"; // 替换成你的实际书名 fprintf(myFile, "%d\t%s\t%s\n", newId, recordDate, bookName); } fclose(myFile); } else { // 文件存在:读取最后一行的BookId,然后自增写入 FILE *myFile = fopen("file.txt", "r"); if (myFile == NULL) { perror("Failed to open file for reading"); return 1; } int lastBookId = 0; char line[256]; // 跳过第一行的列名 fgets(line, sizeof(line), myFile); // 逐行读取,记录最后一个有效的BookId while (fgets(line, sizeof(line), myFile) != NULL) { int currentId; // 解析行首的BookId(假设是整数) if (sscanf(line, "%d", ¤tId) == 1) { lastBookId = currentId; } } fclose(myFile); // 先关闭只读文件 // 以追加模式打开文件,写入新数据 myFile = fopen("file.txt", "a"); if (myFile == NULL) { perror("Failed to open file for appending"); return 1; } // 循环自增BookId并写入 for (int x = 0; x < NR_OF_BOOKS; x++) { int newId = lastBookId + 1 + x; char recordDate[] = "2024-05-20"; // 替换成你的实际数据 char bookName[] = "New Book"; fprintf(myFile, "%d\t%s\t%s\n", newId, recordDate, bookName); } fclose(myFile); } return 0; }
3. 关键注意点
- 必须初始化指针后再判断:永远不要用未初始化的局部指针做NULL判断,这是C语言里的常见低级坑。
- 错误处理不能少:每次
fopen都要检查返回值,避免空指针导致程序崩溃。 - 文件模式选择:新增数据用
"a"追加模式,绝对不要用"w"(会直接清空原有文件内容)。 - 数据格式兼容:如果你的
Book_Id是字符串类型,要调整sscanf的解析逻辑,比如改用%s读取。
内容的提问来源于stack exchange,提问作者Klayd Pro
相关产品推荐
相关产品推荐

