【问题标题】:Can't read from File properly无法正确读取文件
【发布时间】:2021-12-07 22:49:22
【问题描述】:

我正在尝试创建一个程序,其中可以使用推荐的信息创建帐户并将其存储在文件中。

然后会有另一个功能,它将打印存储在文件中的那些信息。这些信息被输入到SignUp 函数中。

将这些信息保存在File中后,.txt文件信息很奇怪(包括.txt文件图像)。

当我尝试调用函数 Information() 来打印之前存储的信息时,要么没有打印,要么打印了一些奇怪的文本。(还包括输出图像)。

我希望我把我的问题说清楚了,有人可以解释我在哪里犯了错误。

下面给出的必要代码。我为SignUP创建了两个函数(它将获取必要的信息并将它们存储在文件中)SignIN 来验证我的用户名和密码。 Information() 函数显示取自 SignUP 的输入并打印出来。

Output & the File.txt image

struct information
{
char username[10];
char password[10];
int date, month, year;
int pnumber[20];
char fname[20];
char lname[20];
char fathname[20];
char mothname[20];
char address[50];

};

int main()
{
int i;
printf("1. SIGN IN\n2. SIGN UP\n");
printf("CHOOSE AN OPTION: ");
scanf("%d", &i);


switch(i)
{

case 1:
    signin();

case 2:
    signup();

}

mainmenu();

}

void info()
{
system("cls");
FILE* fp;
int choice, i;
fp = fopen("username.txt", "rb");
struct information u1;

if (fp == NULL)
{
    printf("error in opening file");
}

        gotoxy(28, 2);
        printf("..........................");
        gotoxy(55, 6);
        printf("==== YOUR ACCOUNT INFO ====");
        gotoxy(55, 8);
        printf("***************************");
        gotoxy(55, 10);
        printf("NAME..%s %s", u1.fname, u1.lname);

        gotoxy(55, 12);
        printf("FATHER's NAME..%s %s", u1.fathname, u1.lname);

        gotoxy(55, 14);
        printf("MOTHER's NAME..%s", u1.mothname);

        gotoxy(55, 18);
        printf("MOBILE NUMBER..%d", u1.pnumber);

        gotoxy(55, 20);
        printf("DATE OF BIRTH.. %d-%d-%d", u1.date, u1.month, u1.year);

        gotoxy(55, 22);
        printf("ADDRESS..%s", u1.address);

    int choose;
    printf("WOULD YOU LIKE TO GO BACK TO MAIN MENU?:\n");
    printf("< 1 > YES\n");
    printf("< 2 > NO\n");
    scanf("%d", &choose);

    if (choose == 2)
    {
        menuExit();
    }
    else
        mainmenu();
}

void signup()
{
char password[20];
int passwordlength, i, seek = 0;
char ch;
FILE *fp, *fu;
struct information u1;
struct information p1;


// Opening file to
// write data of a user
fp = fopen("username.txt", "ab");

system("cls");
printf("\n\n!!!!!CREATE YOUR ACCOUNT!!!!!");

printf("\n\nFIRST NAME...");
scanf("%s", &u1.fname);

printf("\nLAST NAME...");
scanf("%s", &u1.lname);

printf("\nFATHER's NAME...");
scanf("%s", &u1.fathname);

printf("\nMOTHER's NAME...");
scanf("%s", &u1.mothname);

printf("\nADDRESS..");
scanf("%s", &u1.address);

printf("\nDATE OF BIRTH...");
printf("\nDATE-");
scanf("%d", &u1.date);
printf("\nMONTH-");
scanf("%d", &u1.month);
printf("\nYEAR-");
scanf("%d", &u1.year);

printf("\nPHONE NUMBER...");
scanf("%s", u1.pnumber);

printf("\nUSERNAME.. ");
scanf("%s", &u1.username);

printf("\nPASSWORD..");
scanf("&d", &u1.password);

// Taking password in the form of stars
for (i = 0; i < 50; i++)
{
    ch = getch();
    if (ch != 13)
    {
        password[i] = ch;
        ch = '*';
        printf("%c", ch);
    }
    else
        break;
}

fwrite(&u1, sizeof(u1), 1, fp);

fclose(fp);
printf("\n\nACCOUNT CREATED SUCCESSFULLY.\n");

char option[10];
printf("\nPRESS ANY KEY THEN ENTER TO GO TO SIGN IN PAGE");
scanf("%s", &option);
signin();
}

void signin()
{
system("cls");

char username[50];
char password[50];

int i, j, k;
char ch;
FILE *fp, *fu;
struct information u1;


// Opening file of
// user data
fp = fopen("username.txt","rb");

if (fp == NULL)
{
    printf("\nERROR IN OPENING FILE\n");
    printf("FILE DOESN'T EXIST\nYOU HAVE TO CREATE AN ACCOUNT FIRST\n");
    printf("PRESS ANY KEY & ENTER TO CREATE AN ACCOUNT\n");
    char option[10];
    scanf("%s", &option);
    signup();
}
gotoxy(34, 2);
printf(" ACCOUNT LOGIN ");
gotoxy(7, 5);
printf("***********************************************"
       "********************************");

gotoxy(35, 10);
printf("==== LOG IN ====");

// Take input
gotoxy(35, 12);
printf("ENTER USERNAME.. ");
scanf("%s", &username);

gotoxy(35, 14);
printf("ENTER PASSWORD..");

// Input the password
for (i = 0; i < 50; i++)
{
    ch = getch();
    if (ch != 13)
    {
        password[i] = ch;
        ch = '*';
        printf("%c", ch);
    }

    else
        break;
}

// Checking if username
// exists in the file or not
while (fread(&u1, sizeof(u1), 1, fp))
{
    if (strcmp(username, u1.username) == 0)
    {
        mainmenu();
    }
    else
    {
        printf("\n\n\nINFORMATION INCORRECT. PRESS ANY KEY & ENTER TO TRY AGAIN\n");
        char option[10];
        scanf("%s", &option);
        signin();
    }

}


fclose(fp);
}

【问题讨论】:

  • 首先,您应该正确缩进代码以提高其可读性。我数了 3 fopen,只有 2 fclose,我不确定这是个好主意。最后,您经常使用scanf,而不控制返回值或读取值。首先检查您阅读的内容是否正确,然后再将其写入文件(名为“print_info”的函数应该很有用)。关于scanf的好读物:sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
  • "将这些信息保存在文件中后,.txt 文件信息很奇怪" 您将整个结构存储在二进制文件中。不要期望得到可以在文本编辑器中阅读的内容
  • 你读取密码的方式是错误的 - 出于多种原因 - 但最糟糕的是你永远不会从零终止字符串
  • sigin 中,您读取了密码,但您不使用它。奇怪。
  • 电话号码int pnumber[20];有误。根据scanf("%s", u1.pnumber); 的要求,它应该是一个字符串

标签: c file


【解决方案1】:

好吧,您的代码中有很多错误,甚至还有更多“不良做法”示例。来几张吧。

scanf("%s", &u1.fname);

这既错误又危险。

  1. 不应使用&amp;,因为fname 是一个字符数组

  2. %s 没有尺寸(宽度)规范是你不应该做的事情

  3. scanf 的返回值应始终检查

所以代码应该是:

if (scanf("%19s", u1.fname) != 1)
{
    // Input error
    ... add error handling here...
}

下一步:

scanf("&d", &u1.password);

这里你使用%d,意思是“扫描一个整数”,但password是一个字符数组。这显然是一个错误。

scanf("%s", u1.pnumber);

这里你使用%s,意思是“扫描字符”,但pnumber是一个整数数组。这显然是一个错误。

在函数signin 中有读取密码的代码。但是,您的代码永远不会使用您读取的值。奇怪...可能是一个错误。

还要注意password 变量的大小不同。有时是 10,有时是 20,有时是 50。当它是 20 时,您仍然允许用户输入 50 个字符。这很糟糕……非常糟糕。

还有更多。

也就是说,我认为您主要对以下内容感到困惑:

将这些信息保存在File中后,.txt文件信息很奇怪

您正在做的是将整个struct information 对象写入二进制文件。这意味着结构的每个字节(以及它可能具有的任何填充)都将作为原始值写入文件。例如,int pnumber[20]; 将导致文件包含 20 个整数,采用系统使用的任何原始格式。

此类二进制文件无法在记事本等文本编辑器中打开。你只会得到各种奇怪的符号。

所以你的期望是错误的。您的 .txt 不是真正的文本文件,无法使用简单的测试编辑器读取。

这并不意味着文件是错误的。可能没问题,但在文本编辑器中打开它没有意义。

【讨论】:

  • 感谢您的澄清。我现在可以理解我的一些笨拙错误了。但是,您能否向我解释一下 Information() 有什么问题以及为什么它现在可以正确显示信息?我该如何解决?
  • 你在这里。在 Information() @4386427 中仍然有同样的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
  • 2018-07-24
  • 2020-03-11
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多