尝试将c中的结构写入文件,然后稍后再读回来

问题描述 投票:0回答:1

我编写了一段代码,可以轻松地以某种格式写入文件结构。

但是当谈到读回这些信息时,我完全失败了。这是代码:

const char *USER_INFO_OUT = "(%s, %s, %s, %s, %c, %s, %s, %s, %.3lf, %.3lf, %.3lf)";
const char *USER_INFO_IN = "(%[^,], %[^,], %[^,], %[^,], %c, %[^,], %[^,], %[^,], %.3lf, %.3lf, %.3lf)";

typedef struct user
{
    char TCID[100];
    char fullname[100];
    char email[100];
    char phone[100];
    char gender;
    char address[100];
    char password[100];
    char customerID[100];
    double balance;
    double savings;
    double debt;
} user;

user usr1;

void signup() {
    FILE *fp;
    system("cls");
    printf("\n\t\t\t--------------REGISTER A NEW ACCOUNT--------------\n\n\n");
    
    printf("\n\tEnter Your Full Name:\t");
    fgetc(stdin);
    takeinput(usr1.fullname);
    printf("\n\tEnter Your Tc. ID NO:\t");
    takeinput(usr1.TCID);
    printf("\n\tEnter Your e-mail:\t");
    takeinput(usr1.email);
    printf("\n\tEnter Your Phone No:\t");
    takeinput(usr1.phone);
    printf("\n\tEnter Your Gender M/F:\t");
    scanf("%c", &usr1.gender);
    fgetc(stdin);
    printf("\n\tEnter Your address:\t");
    takeinput(usr1.address);
    printf("\n\tEnter Your password:\t");
    takepassword(usr1.password);
    printf("\n\tEnter Your password again:\t");
    takepassword(password2);
    if (!strcmp(usr1.password, password2)) {
        customerid(usr1.customerID);
        system("cls"); 
        char folder[100] = "users\\"; //here starts the File Writing Code
        strcat(folder, usr1.customerID);
        strcat(folder, ".dat");
        fp = fopen(folder, "a+");
        fprintf(fp, USER_INFO_OUT, usr1.fullname, usr1.TCID, usr1.email, usr1.phone, usr1.gender, usr1.address, usr1.password, usr1.customerID, usr1.balance, usr1.savings, usr1.debt); // here it ends
        printf("\n\t\t\t--------------REGISTERATION COMPLETED--------------\n\n\n");
        PlaySound(TEXT("Sounds\\signupdone.wav"), NULL, SND_ASYNC);
        printf("\n\tYou succesfully created an account %s", usr1.fullname);
        printf("\n\tThis is your Customer ID:\t%s", usr1.customerID);
        printf("\n\nSave Your Customer ID to Log in to Your account later!");
        fclose(fp);
    } else {
        PlaySound(TEXT("Sounds\\invpass.wav"), NULL, SND_ASYNC);
        printf("\n\n\t Redirecting to main menu...");
        Sleep(4000);
        registar();
    }
}

void login() { //***this is the problem ***
    FILE *f;
    system("cls");
    printf("\n\t\t\tWELLCOME BACK TO AVCI BANK\n\n");
    printf("\n\t\tPlease enter Your Customer ID: \t");
    fgetc(stdin);
    takeinput(usr1.customerID);
    char folder[100] = "users\\";
    strcat(folder, usr1.customerID);
    strcat(folder, ".dat");
    f = fopen(folder, "r");
    if (f == NULL) //this part works fine! if it can't find a file named "folder" it executes here
    {
        printf("\n\n\tSorry This Account Doesn't Exist.\n\t Contact us for further information or Create a new account");
        system("pause");
        registar();
    } else { //but when I enter a correct ID(file name) the program stops running. It crushes and closes immediately
        fseek(f, 0, SEEK_SET);
        fscanf(f, USER_INFO_IN, usr1.fullname, usr1.TCID, usr1.email, usr1.phone, &usr1.gender, usr1.address, usr1.password, usr1.customerID, &usr1.balance, &usr1.savings, &usr1.debt);
        system("cls");
        printf("%s\t%s\t%s\t%s\t", usr1.fullname, usr1.TCID, usr1.email, usr1.address);
        system("pause");
    }
}

我正在尝试读取保存到文件中的信息并将该信息放回结构中以供使用。

但是当

fscanf
函数运行时,程序立即关闭。可能会崩溃。我不知道为什么。您能更正一下代码吗?我真的不知道如何从文件中读回结构

基本上,如何在 C 中读取逗号分隔的文件并将值附加到结构中? 重要:

const char *USER_INFO_IN = "(%[^,] %[^,] %[^,] %[^,] %c %[^,] %[^,] %[^,] %.3lf %.3lf %.3lf)"; 

我认为问题与此有关。 通常,当我在 VSCode 中输入格式说明符时,它应该变成浅绿色。但是当我输入

%[^,]
时,它应该意味着读到逗号,它不会将其视为格式说明符,
%
是红色,
[^,]
是橙色。它将它们视为单独的事物。

c file authentication struct scanf
1个回答
0
投票

使用变量来保存

scanf
printf
的格式字符串是一个坏主意:

  • VSCode 无法脱离上下文理解这些字符串。
  • 高级编译器(例如 gccclang)可以在格式字符串与传递给
    scanf
    和/或
    printf
    的实际参数之间执行一致性检查,但前提是格式字符串作为字符串文字传递。

您的格式字符串存在一些不一致:

  • %[^,]
    是有风险的,因为
    scanf
    没有有关目标数组长度的信息,因此如果输入无效,则可以写入超出数组末尾的内容。使用
    %99[^,]
    可以防止这种情况发生。
  • scanf
    格式
    %.3lf
    毫无意义。 scanf 没有
     precision
    字段。 width字段用于限制从输入中读取的字符数,但格式字符串中的
    .
    被解释为无效的转换说明符,导致
    scanf()
    失败。只需使用
    %lf
© www.soinside.com 2019 - 2024. All rights reserved.