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

C语言账户管理程序运行时无法打开目标文件的技术求助

C语言客户账户管理程序文件打开失败问题

我编写了一款C语言客户账户管理程序,用于收集用户账号、姓名、余额、信用额度等信息,程序支持判断用户是否为新用户,新用户可创建新记录。但运行程序时,目标文件ACCT.txt始终无法打开,我已通过if-else语句检测到文件打开失败的情况,运行后控制台输出File could not be opened.,以下是完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct clientData{
char name[20];
int accNum;
float balance;
float limit;
};

void print(FILE *fPtr) {
rewind(fPtr);
struct clientData client={"",0,0.0,0.0};
printf("%-35s %-20s %-20s %-20s\n","NAME","ACCOUNT#","BALANCE","CREDIT LIMIT");
while(fread(&client,sizeof(struct clientData),1,fPtr) && !feof(fPtr)){
    if(client.accNum!=0)
        printf("%-35s %-20d %-20.2f %-20.2f\n",client.name,client.accNum,client.balance,client.limit);
}
}

int checkExist(FILE *fPtr,struct clientData client){
struct clientData temp;
fseek(fPtr,(client.accNum/50-1)*sizeof(struct clientData),SEEK_SET);
fread(&temp,sizeof(struct clientData),1,fPtr);
if(temp.accNum==client.accNum)
    return 1;
return 0;
}

int checkName(char name[]){
int i;
for(i=0;i<strlen(name);i++){
    name[i]=toupper(name[i]);
    if(!(name[i]>='A' && name[i]<='Z' || name[i]==' '))
        return 0;
}
 return 1;
}
void findName(char name[]){
printf("ENTER CUSTOMER NAME\n");
getchar();
fgets(name,30,stdin);
name[strlen(name)-1]='\0';
while(!checkName(name)){
    printf("RE-ENTER CUSTOMER NAME.\n");
    getchar();
    fgets(name,30,stdin);
    name[strlen(name)-1]='\0';
}
}

void checkLimit(float *limitNum){
while(*limitNum<0){
    printf("RE-ENTER CUSTOMER CREDIT LIMIT.\n");
    scanf("%f",limitNum);
    }
}

void newRecord(FILE *fPtr,struct clientData client){
if(!checkExist(fPtr,client)){
    findName(client.name);
    printf("ENTER CUSTOMER CREDIT LIMIT\n");
    scanf("%f",&client.limit);
    checkLimit(&client.limit);
    if(client.balance<=client.limit || client.limit==0){

        printf("DEAR %s\n"
               "THANK YOU FOR YOUR BUSINESS\n",client.name);
            fseek(fPtr,(client.accNum/50-1)*sizeof(struct clientData),SEEK_SET);
              fwrite(&client,sizeof(struct clientData),1,fPtr);
    }
    else
        printf("Dear %s\n"
                       " WE CANNOT AUTHORIZE THIS PURCHASE AT THIS TIME AS IT\n"
                           "WOULD PUT YOU %.2f EURO OVER YOUR CREDIT LIMIT.\n",client.name,(client.balance));

}
else printf("ACCOUNT ALREADY EXISTS - RE ENTER DATA.\n");
}
void modifyRec(FILE *fPtr,struct clientData client){

             double new_balance;
             if(checkExist(fPtr,client)){
                new_balance=client.balance;
                fseek(fPtr,(client.accNum/50-1)*sizeof(struct clientData),SEEK_SET);
                fread(&client,sizeof(struct clientData),1,fPtr);
                if(client.balance<=client.limit || client.limit==0){

                    printf("DEAR %s\n"

               "THANK YOU FOR THE BUSINESS.\n",client.name);
                    fseek(fPtr,(client.accNum/50-1)*sizeof(struct clientData),SEEK_SET);
                    fwrite(&client,sizeof(struct clientData),1,fPtr);
                }else
                printf("Dear %s\n"
                       " WE CANNOT AUTHORIZE THIS PURCHASE AT THIS TIME AS IT\n"
                           "WOULD PUT YOU %.2f EURO OVER YOUR CREDIT LIMIT.\n",client.name,(client.balance));


             }else {
             printf("ACCOUNT DOES NOT EXIST - RE ENTER DATA.\n");

}

}
void checkAccNum(int *accountNumber){
while(*accountNumber%50!=0 && *accountNumber>0){
    printf("RE ENTER ACCOUNT NUMBER.\n");
    scanf("%d",accountNumber);
}
}
void checkBalance(float *balanceNum){
while(*balanceNum<0){
    printf("RE ENTER BALANCE.\n");
    scanf("%f",balanceNum);
  }
 }
void check(FILE *readPtr)
{
    struct clientData client={"",0,0.0,0.0};
    char answer;
    printf("ENTER ACCOUNT NUMBER\n");
    scanf("%d",&client.accNum);
    checkAccNum(&client.accNum);

        while(client.accNum>0){
            printf("ENTER AMOUNT OF PURCHASE\n");
            scanf("%f",&client.balance);
            checkBalance(&client.balance);
            printf("IS THIS A NEW ACCOUNT NUMBER?(Y OR N):\n");
            getchar();
            scanf("%c",&answer);
            if(answer=='N'){
              modifyRec(readPtr,client);
            }
          else
            if(answer=='Y'){
             newRecord(readPtr,client);
          }
          printf("ENTER ACCOUNT NUMBER\n");
          scanf("%d",&client.accNum);
        }
    }



int main()
{
    FILE *fPtr;
    if((fPtr=fopen("ACCT.txt","r+"))==NULL)
        printf("File could not be opened.\n");
    else {
        print(fPtr);
        check(fPtr);
    }
    return 0;
}

问题排查及解决方法

  • 文件路径错误:程序使用相对路径时,ACCT.txt必须和生成的可执行文件在同一目录。如果文件在其他位置,要替换为完整绝对路径,比如Windows下写"C:\\Users\\你的用户名\\ACCT.txt",Linux/macOS下写"/home/你的用户名/ACCT.txt"。
  • 文件不存在导致打开失败:r+模式要求文件必须已存在才能打开。如果是首次运行,文件还未创建,可修改main函数中的文件打开逻辑,先尝试r+,失败则创建文件:
int main()
{
    FILE *fPtr;
    if((fPtr=fopen("ACCT.txt","r+"))==NULL){
        // 尝试创建文件
        fPtr = fopen("ACCT.txt","w+");
        if(fPtr == NULL){
            printf("文件无法打开或创建。\n");
            return 1;
        }
    }
    print(fPtr);
    check(fPtr);
    fclose(fPtr); // 记得关闭文件
    return 0;
}
  • 权限问题:Linux/macOS下,当前用户可能没有该文件的读写权限,执行chmod 644 ACCT.txt赋予读写权限;Windows下检查文件是否被其他程序占用,或右键设置文件权限为当前用户可读写。
  • 额外优化:结构体读写可能因编译器对齐导致异常,建议在结构体定义前添加#pragma pack(1)取消内存对齐,确保不同环境下结构体大小一致:
#pragma pack(1)
struct clientData{
char name[20];
int accNum;
float balance;
float limit;
};
#pragma pack()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:35:22