You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言程序中fopen写入文件失败,请求问题排查与解决

问题排查与修复:密码验证后文件创建写入失败

你遇到的文件创建写入功能异常,主要是代码里的几个细节问题导致的,我帮你逐一拆解:

1. CreateFile 打开的文件句柄未关闭,导致 fopen 无法访问文件

你用 CreateFileA 创建文件后,没有调用 CloseHandle(h) 关闭这个句柄。由于 CreateFile 默认的共享模式是 NULL(不允许其他句柄访问该文件),后续调用 fopen 会因为文件已被当前进程占用而失败,fp 会变成 NULL,这时执行 fprintf 就会触发未定义行为(程序崩溃或无写入效果)。

2. 局部变量重定义覆盖了文件指针

在 if (fp == NULL) 的代码块里,你重新定义了 FILE *fp;,这会覆盖外面声明的同名指针变量。即使 fopen 成功,后续操作的也是这个局部变量,逻辑上会出现混乱。

3. 缺少关键的错误检查

你没有检查 CreateFileA 和 fopen 的返回值是否成功:

  • 如果目标目录(比如 C:\\Users\\shai\\Desktop\\Create\\)不存在,CreateFileA 会返回 INVALID_HANDLE_VALUE,无法创建文件;
  • 如果 fopen 失败(比如文件被占用),直接调用 fprintf 会出问题。

4. 密码验证的小问题(额外提示)

你调用 strcmp 时写了 strcmp(SecretPass, &Userinput),Userinput 是数组名,本身就是指向数组首元素的指针,不需要加 &,改成 strcmp(SecretPass, Userinput) 才对。另外,fgets 会读取输入的换行符(如果输入长度小于缓冲区大小),可能导致密码匹配失败——可以用 strcspn 去掉 Userinput 里的换行符。


修复后的完整代码

#include <stdio.h>
#include <Windows.h>
#include <string.h>
#pragma warning(disable:4996)

int main() {
    char SecretPass[7] = "Az1236";
    char Userinput[7];
    int ResultCMP;

    printf_s("Insert Pass:");
    fgets(Userinput, 7, stdin);
    // 去掉fgets读入的换行符,避免密码匹配失败
    Userinput[strcspn(Userinput, "\n")] = '\0';
    // 修正strcmp的参数,不需要&Userinput
    ResultCMP = strcmp(SecretPass, Userinput);

    if (ResultCMP == 0) {
        int msg = MessageBox(NULL, "You Got In", "Wow", MB_ICONEXCLAMATION);
        if (msg == IDOK) {
            printf_s("Great! \n");
            char *szFileName = "C:\\Users\\shai\\Desktop\\Create\\kilroy.txt";
            
            // 先检查文件是否存在
            FILE *fp = fopen(szFileName, "r");
            if (fp == NULL) {
                // 先确保目录存在(如果目录不存在,CreateFile会失败)
                char dirPath[MAX_PATH];
                strcpy(dirPath, szFileName);
                // 去掉文件名,只保留目录
                char *lastSlash = strrchr(dirPath, '\\');
                if (lastSlash != NULL) {
                    *lastSlash = '\0';
                    // 创建目录,已存在的话不会报错
                    CreateDirectoryA(dirPath, NULL);
                }

                // 直接用fopen创建写入(更简洁的C标准库方案)
                fp = fopen(szFileName, "w+");
                if (fp != NULL) {
                    fprintf(fp, "testtest");
                    puts("Done");
                    fclose(fp);
                } else {
                    printf("Failed to open file for writing!\n");
                }
            } else {
                printf("File exists!\n");
                fclose(fp); // 记得关闭已打开的文件
            }
        } else {
            printf_s("Wrong pass!");
            getchar();
        }
    } else {
        // 新增密码错误的提示,否则用户看不到反馈
        printf_s("Wrong password!\n");
        getchar();
    }

    getchar();
    return 0;
}

额外说明

  • 我用了更简洁的 fopen 直接创建文件的方案,如果你一定要保留 CreateFile 的逻辑,记得在创建后立即调用 CloseHandle(h) 释放句柄,再用 fopen 打开;
  • 添加了创建目录的逻辑,因为如果 Create 文件夹不存在,任何文件创建操作都会失败;
  • 完善了错误提示,方便你快速定位问题;
  • 修复了密码验证里的换行符问题,避免用户输入正确密码但匹配失败的情况。

内容的提问来源于stack exchange,提问作者Xozu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:32:54