有关文件内容修改错误

我想更改文本中的密码,就写了这样一个密码更改函数。各种调试都好好的,就是成功进入if语句新密码相等时程序直接就结束了,为什么啊。。

void gotoxy(int x,int y)//光标定位函数
{
    COORD p;//定义结构体变量p
    HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);//获取当前函数句柄
    p.X=x;p.Y=y;//将光标的目标移动位置传递给结构体
    SetConsoleCursorPosition(handle,p);//移动光标
}
typedef struct password{
    char id[8];
    char pass_word[8];
}Password;
void modify_stu(){
        int index;int x1,x2;
        char a2,a,b,c;char password1[8];char id1[8];
        char new1_password[8],new2_password[8];
        FILE *fp;
        char filename[30] = { "账号密码管理.txt" };
            if ((fp = fopen(filename, "r+")) == NULL){
                    printf("can not open!\n");
                    getchar();
                    exit(0);
               } 
        Password *present;
        system("cls");
        printf("*************************************************************************\n");
        printf("***                  欢迎进入密码修改界面                             ***\n");
        printf("***       请输入账号___________                                       ***\n");
        printf("***       请输入密码___________                                       ***\n");
        printf("***                                                                   ***\n");
        printf("*************************************************************************\n");
        gotoxy(20,2);
        int i;int x,y,z1,z2;
        for(i=0;;i++){
            index=0;
            x=0;y=0;z1=0;z2=0;
            while(y<7){
                a2=getch();
                if(a2=='\b'){
                    if(y>0){
                        id1[y-1]='\0';
                        y--;
                    }
                    printf("\b \b");
                    continue;
                }
                if(a2!='\r'){
                    id1[y++]=a2;
                    putchar(a2);
                }
                else
                    break;
            }
            id1[y]='\0';
            gotoxy(20,3);
            while (x<7 ){
                a = getch();
                if (a == '\b'){
                    if (x>0){
                        password1[x - 1] = '\0';
                        x--;
                    }
                    printf("\b \b");//先让光标退回一格然后空格覆盖掉要删除字符,然后退回一格重新输入
                    continue;
                }
                if (a != '\r'){
                    password1[x++] = a;
                    putchar('*');
                }
                else
                    break;
            }
            password1[x] = '\0';
            if (Password_confirm(id1,password1)==1){
                index = 1;
                break;
            }
            else{
                    for(int j=0;j<=x-1;j++)
                    printf("\b \b");
                    gotoxy(20,2);
                    printf("________");
                    gotoxy(20,4);
                    printf("密码错误,请输入正确密码\n");
                    gotoxy(20,2);
                }


            
        }
        if (index == 1){//success    
            system("cls");    
            printf("请输入新密码  ");
            x1=0,x2=0;
            while (x1<7 ){
                b = getch();
                if (b == '\b'){
                    if (x1>0){
                        new1_password[x1 - 1] = '\0';
                        x1--;
                    }
                    printf("\b \b");//先让光标退回一格然后空格覆盖掉要删除字符,然后退回一格重新输入
                    continue;
                }
                if (b != '\r'){
                    new1_password[x1++] = b;
                    putchar('*');
                }
                else
                    break;
            }
            new1_password[x1] = '\0';
            printf("\n请再次输入新密码     ");
            while (x2<7 ){
                c = getch();
                if (c == '\b'){
                    if (x2>0){
                        new2_password[x2 - 1] = '\0';
                        x2--;
                    }
                    printf("\b \b");//先让光标退回一格然后空格覆盖掉要删除字符,然后退回一格重新输入
                    continue;
                }
                if (c != '\r'){
                    new2_password[x2++] = c;
                    putchar('*');
                }
                else
                    break;
            }
            new2_password[x2] = '\0';
            if(strcmp(new1_password,new2_password)==0){
                        FILE *fp;
                       char filename[30] = { "账号密码管理.txt" };
                       fp = fopen(filename, "r+"); 
                    while(fread(present,sizeof(Password),1,fp)==1){//每次读入一个结构体长度的数据,返回1则代表读取成功
                        if(strcmp(present->id ,id1)==0){//如果Present所指向的结构体名字与文件中字符串配对成功
                             strcpy(present->pass_word,password1);
                             printf("%s",present->pass_word); 
                               fseek(fp,-sizeof(Password),SEEK_CUR);//指针移至修改目标前
                            fwrite(present,sizeof(Password),1,fp);//将结构体中的内容写入文件
                            fflush(fp);
                            fclose(fp);
                             break;//退出循环
                    }
                    else
                    printf("%s\t%s",present->id,id1);
                }    
            }
            else{
            printf("%s\t%s",new1_password,new2_password); 
            fclose(fp);                
            }            
        }
    
       
}

Password_confirm(id1,password1)这个是判断密码账号密码是否正确的函数
其中主体代码是对的,就是判断之后新密码相等成功后程序就结束了,问题就出在if(strcmp(new1_password,new2_password)==0)里面的代码

该回答引用ChatGPT4与博主@晓码自在合作编写:

这里的问题是:if语句判断新密码相等成功后,直接执行了fclose(fp),关闭了文件指针。然后程序就结束了,没有执行后续的代码。

解决办法是:不要在if语句内关闭文件指针fp。应该在整个函数结束后统一关闭:

c
void modify_stu(){
    // ...
    if(strcmp(new1_password,new2_password)==0){ 
        // 修改密码逻辑
    } else {
        // 新密码不相等,错误提示
    }
    
    fclose(fp);  // 在函数结束处关闭文件指针
}

这样,无论if语句判断结果如何,程序都会继续执行,直到函数结束,然后在函数结束处统一关闭文件指针fp。

修改后的代码如下:

c
void modify_stu(){
        // ...
        if(strcmp(new1_password,new2_password)==0){
                        // 修改密码逻辑  
                       
        }
        else{
            printf("%s\t%s",new1_password,new2_password);      
        }
} 
 fclose(fp);

在函数结束处添加fclose(fp)关闭文件指针。这样无论if语句判断结果为true还是false,函数都会继续执行,直到结束,然后关闭文件指针。

总结:对于打开的文件资源如文件指针,应该在函数结束时统一关闭,而不是在if语句内关闭,否则if语句判断失败,文件资源不会关闭,导致资源泄漏。

根据你提供的代码,问题可能出现在if(strcmp(new1_password,new2_password)==0)条件语句块中。请注意以下几点:

  1. 文件指针位置:在写入修改后的密码之前,确保文件指针的位置正确。你可以在调用fwrite之前使用ftell获取当前文件指针位置,并在fwrite之后使用fflush刷新文件缓冲区。

  2. 文件打开模式:你使用的是"r+"模式打开文件,它允许读取和写入。但是,对于freadfwrite函数,你需要确保文件指针在正确的位置。在写入之前,使用fseek将文件指针移至要修改的记录的起始位置。

  3. 结构体指针初始化:在使用fread函数之前,确保你已经为present结构体指针分配了内存空间。可以使用malloc函数或声明一个结构体变量,然后使用&运算符将其地址赋给指针。

以下是可能修复问题的示例代码:

// 修复问题的示例代码

void modify_stu() {
    int index;
    // ...
    Password* present = malloc(sizeof(Password));
    // ...
    if (index == 1) {
        // ...
        if (strcmp(new1_password, new2_password) == 0) {
            FILE* fp;
            char filename[30] = { "账号密码管理.txt" };
            fp = fopen(filename, "r+");
            if (fp == NULL) {
                printf("can not open!\n");
                getchar();
                exit(0);
            }
            while (fread(present, sizeof(Password), 1, fp) == 1) {
                if (strcmp(present->id, id1) == 0) {
                    strcpy(present->pass_word, password1);
                    fseek(fp, -sizeof(Password), SEEK_CUR);
                    fwrite(present, sizeof(Password), 1, fp);
                    fflush(fp);
                    fclose(fp);
                    break;
                }
            }
        }
        else {
            printf("%s\t%s", new1_password, new2_password);
            fclose(fp);
        }
        free(present); // 释放结构体指针内存
    }
    // ...
}

请确保在使用malloc分配内存后,使用free函数释放分配的内存,避免内存泄漏。

同时,也建议在打开文件和内存分配失败时进行适当的错误处理和提示,以提高程序的鲁棒性。

你可以试着将文件的读写方式改为 "r+b",并在修改完成之后使用 fclose(fp) 关闭文件,同时将之前的文件句柄重新打开一次,然后进行保存操作,具体代码

// 将文件的读写方式改为 "r+b"
fp = fopen(filename, "r+b"); 
while (fread(present, sizeof(Password), 1, fp) == 1) {
    if (strcmp(present->id ,id1) == 0) {
        strcpy(present->pass_word, new2_password);
        fseek(fp, -sizeof(Password), SEEK_CUR);
        fwrite(present, sizeof(Password), 1, fp);
        fflush(fp);
        fclose(fp);
        fp = fopen(filename, "r+");
        break;
    }
}
fclose(fp);

这样做的话,就可以在修改完成之后再次打开文件进行保存操作,确保新密码能够正确地被保存到文件中。


#include <stdio.h>
#include <windows.h>
#include <string.h>
int main(void)
{
    int n = 0;
    char  password[20] = { 0 };
    char l[20] = { 0 };
    char k[20] = { 0 };
    printf("请输入修改密码:>");
    scanf("%s", &l);
    printf("请再次确认密码:>");
    scanf("%s", &k);
    while (strcmp(l, k) != 0)//strcmp两个字符串比较函数在#include<string.h>文件中使用
    {
        printf("两次密码不一致,请从新输入:\n");
        printf("请输入修改密码:>");
        scanf("%s", &l);
        printf("请再次确认密码:>");
        scanf("%s", &k);
        continue;
    }
    printf("设置密码成功:\n");
    Sleep(1000);//延迟函数在#include <windows.h>中使用 
    system("cls");//system(" ")执行系统命令函数, cls表示清空清空屏幕
    for (n = 0; n < 3; n++)
    {
        printf("请输入登录密码:>");
        scanf("%s", &password);
        if (strcmp(password, k) == 0)
        {
            printf("登录成功\n");
            break;
        }
        else
        {
            printf("密码错误,请重新输入\n");
        }
    }
    if (n == 3)
    {
        printf("三次密码均错误,退出程序\n");
    }
    return 0;
}

应该是你 if(strcmp(new1_password,new2_password)==0){ 这里比较的问题,new1_password和new2_password都是字符串数组,先转为字符串再使用strcmp比较大小,应该是你这里的if判断一直不成功,导致每次进入了else条件,导致程序直接结束。

把报错信息贴出来。根据报错信息提示才能更好判定具体问题

该回答引用ChatGPT

从代码来看,密码修改成功后,程序直接结束的原因可能是:

  1. 修改密码成功后,忘记添加程序退出逻辑,导致程序直接结束。
    解决方案是在成功修改密码后,添加如下代码:
    c
printf("密码修改成功!\n");
system("pause");  // 或者getchar();

这将在修改成功后提示用户并等待用户输入,避免程序直接结束。
2. 修改密码成功后,文件资源没有正确关闭,导致程序崩溃。
在代码中,打开文件的语句是:
c

fp = fopen(filename, "r+");  

但是在成功修改密码后,忘记添加文件关闭语句:
c

fclose(fp);

这会导致文件资源泄露,程序崩溃。解决方案是在修改密码成功后添加文件关闭语句。
3. 读取文件和写入文件没有正确匹配,导致密码只修改了内存中的数据,实际文件中密码未变。
在代码中,读取账号密码信息是通过:
c

fread(present,sizeof(Password),1,fp)==1  

修改密码后,写入文件是通过:
c

fwrite(present,sizeof(Password),1,fp);

但是,这里的present指针并未在读取后发生变化,所以写入的还是读取的老密码信息,而非新输入的密码。
解决方案是在成功输入新密码后,将新密码信息写入present指针,然后再执行写入文件操作:
c

strcpy(present->pass_word, new_password);   // 将新密码写入present
fwrite(present,sizeof(Password),1,fp);      // 写入新密码

这样就解决了 兄弟