这个程序中的恐惧错误了吗?
我是C的中级学生。我正在尝试制作银行管理程序,但首先我需要制作一个登录程序,所以我创建了以下其中一项。 我最近在C中了解了文件I / O,并且对fread和fwrite知之甚少。 我有一个文件(data.txt)格式如下,如下。
user1 1124
user2 3215
user3 5431
在下面的程序中,我要求用户输入用户名和密码(4位密码)并将文件数据复制到结构中,然后将这两者进行比较以validation信息。
我的程序有什么问题以及如何使fread正常工作。 是在data.txt文件中格式化还是我应该更改它。
提前致谢…
#include #include #include struct user_account { char u_name[30]; int u_pin; } log_in; int login() { int start; int i, n; int t_pin[4]; // TEMPORARY INT PIN for storing pin inputed by user char t_name[30]; // TEMPORARY STRING for storing name inputed by user FILE *fp; fp = fopen("data.txt","rb"); // Opening record file if(fp == NULL) { puts("Unable to open file!"); return 1; } start : { printf("User Name : "); scanf("%s",&t_name); printf("Pin Code : "); for(i = 0; i < 4; i++) { // This loop is for hiding input pin n = getch(); if(isdigit(n)) { t_pin[i] = n; printf("*"); } else { printf("\b"); i--; } } fread(&log_in,sizeof(log_in),1,fp); // Comparing user name and pin with info in the structure copied from the file if(strcmp(log_in.u_name, t_name) == 0 && log_in.u_pin == t_pin) puts("Login successful! Welcome User"); else { printf("\nIncorrect Information!\n"); printf("Press any key to log in again..."); getch(); system("cls"); goto start; } } } int main() { int login(); return 0; }
问题是你有一个ASCII /文本文件但是你试图使用fread
直接读入一个结构; 这需要二进制格式的文件。 fread
无法进行格式转换。 请改用fscanf
:
fscanf(fp, "%s %d", &log_in.u_name, &log_in.u_pin);
我看到的问题:
-
以下行不正确。
scanf("%s",&t_name);
你需要使用:
scanf("%29s",t_name);
-
给定文件格式,
fread
不是正确的解决方案。 当文件是二进制格式时,fread
有效。根据输入文件的格式,您需要使用:
scanf("%29s %d", log_in.uname, &log_in.u_pin);
-
使用
log_in.u_pin == t_pin
比较引脚应该会产生编译器错误。log_in.u_pin
的类型是int
而log_in.u_pin
的类型是int [4]
。 您将不得不更改从t_pin
获取整数值的t_pin
。您可以使用以下内容:
int pin = 0; for (i = 0; i < 4; ++i ) { pin = 10*pin + t_pin[i]; }
但是,要使其正常工作,您必须在
t_pin
存储正确的整数值。 当您阅读的字符为'1'
,您必须存储1
。 要么是这样,要么你必须将上面的for循环更改为:pin = 10*pin + t_pin[i]-'0';
-
在你的函数中使用
goto start
循环的方式是不正确的。 您还没有从输入文件中读取所有用户ID和引脚并进行比较。 你拥有它的方式,你将最终做到:- 阅读用户名和密码
-
检查文件中的第一个条目。 如果他们不匹配......
-
再次读取用户名和引脚。
- 检查文件中的下一个条目。 如果他们不匹配......
等等
你想要:
-
阅读用户名和密码
-
检查文件中的第一个条目。 如果他们不匹配......
- 检查文件中的下一个条目。 如果他们不匹配......
- 检查文件中的下一个条目。 如果他们不匹配......
等等
a)fread用于读取固定大小(以字节为单位)的记录。 虽然这是一个选项,但您可能会发现fscanf更适合您的用例。
b)goto有其用途,可以说,但在你的特定情况下,while循环更合适,因为它使意图更清晰,更不容易被误用。
c)您的问题的关键是阅读文件。 您只需读入并检查每个传递文件中的单个记录,一旦读取所有记录,您将获得EOF而不是其他记录。
你有几个选择。 您可以在登录循环之前将整个用户表读入列表。 当用户登录时,您必须遍历列表,直到找到匹配或列表结尾。 或者,您可以在每次尝试查找匹配项的用户尝试时遍历整个文件,并在完成后查找返回文件的开头。 在任何一种情况下,您都必须检查并处理读取错误。
d)最后,当输入非数字时,你可能会发现退格不是你想到的。 您也可以考虑允许用户在输入引脚时按退格键。