c - 在我使用文件从结构打印后,它不起作用
问题描述
a- 从文件“detyra_day.dat”中读取并打印数据
b- 当您知道 IDNR 是唯一的时添加另一个公民
c- 在不更改 IDNR 的情况下更改公民的信息
d- 为每个家庭每天仅1人创建“外出许可”申请(申请人可以申请其他家庭成员,申请人必须年满18岁),并且“外出许可”从8开始:00 至 17:00,持续 2 小时。
e- 检查公民是否有权外出(打印 IDNR、日期和时间)。
f- 保存
g- 为所有公民和家庭打印所有“外出许可”。
h- 打印请求许可最多的 10 个公民和请求最少的 10 个公民的列表(不包括根本没有请求的公民)
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <windows.h>
int permission;
int hour;
int minute;
int nr_people;
struct citizen{
char idnr[10];
char name[50];
char lname[50];
long int birthday;
int id_family;
};
struct birthday{
int year;
int month;
int day;
};
char fname[]={"detyra_day.dat"};
void readPeopleInfo(){
nr_people=0;
struct citizen s;
FILE *f;
f=fopen(fname,"r");
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\tname\tlname\tbirthday\tid_family\n\n");
if(f == NULL)
{
printf("Error opening file\n");
exit(1);
}
while(fread(&s,sizeof(struct citizen),1,f))
{
printf("%s\t",s.idnr);
printf("%s\t",s.name);
printf("%s\t",s.lname);
printf("%ld\t",s.birthday);
printf("%d\t\n\n",s.id_family);
nr_people++;
}
fclose(f);
printf("========================================================\n\n");
printf("Number of citizen = %d",nr_people);
}
void add(){
struct citizen s,s1;
int nr_people=5;
int found=0;
printf("\n Give the unique IDNR: ");
scanf("%s",&s1.idnr);
for(int i=0;i<nr_people;i++){
if(s1.idnr==s.idnr){
printf("The citizen with this IDNR exist");
found=1;
return;
}
}
if(found==0){
printf("The citizen with this IDNR doesn't 'exist");
strcpy(s.idnr,s1.idnr);
printf("\nGive the name of the citizen: ");
scanf("%s",s.name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s.lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s.birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s.id_family);
nr_people++;
}
}
void change(){
struct citizen s[50];
char *idnr;
printf("\n IDNR of citizen: ");
scanf("%s",&idnr);
for(int i=0;i<nr_people; i++){
if (strcmp(s[i].idnr,idnr)==0){
printf("\nGive the name of the citizen: ");
scanf("%s",s[i].name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s[i].lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s[i].birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s[i].id_family);
printf("\n Changed succesfully.");
return; }
printf("\n The change didn't happened.");
}
}
void permit(){
int permission;
struct birthday bday;
struct citizen s[50];
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for(int i=0;i<nr_people;i++){
if(bday.month>d.wMonth||(bday.month==d.wMonth&&bday.day>=d.wDay)){
age[i]=d.wYear-bday.year;
}
else{
age[i]=d.wYear-bday.year-1;
}
}
char *name;
char *lname;
char *chosenperson;
int id_family;
int i;
int apply=0;
int familymembers=0;
printf("Put your name: ");
scanf("%s",&name);
printf("Put your lname: ");
scanf("%s",&lname);
for (i=0;i<nr_people;i++){
if((strstr(name,s[i].name)==0&&strstr(lname,s[i].lname)==0&&age[i]>=18)){
printf("Your name is on the list and you are in the age to apply");
id_family=s[i].id_family;
apply=1;
}
}
if(apply==0){
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp;
for(i=0;i<nr_people;i++){
if(id_family==s[i].id_family){
tmp=s[50];
familymembers++;
}
}
for(i=0;i<familymembers;i++){
printf("%d. name: %10s",i+1,tmp.name);
}
apply=0;
printf("Give the name of the person from your family that you want to apply: ");
scanf("%s",chosenperson);
printf("\nYou chose: ");
for(i=0;i<familymembers;i++){
if(strstr(chosenperson,tmp.name)==0){
printf("%s",tmp.name);
apply=1;
}
}
if(apply==0){
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f",&timez);
if(timez>=8.00&&timez<=17.00){
hour=timez;
minute=(timez-hour)*100;
if(minute>59){
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",timez,timez+2);
permission=1;
}
else{
printf("You have chosen the wrong time");
return;
}
}
void control(){
permit();
struct citizen s[50];
SYSTEMTIME d;
GetLocalTime(&d);
int g=permission;
for(int i=0;i<nr_people;i++){
if(g==1){
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",s[nr_people].idnr,d.wYear,d.wMonth,d.wDay,hour,minute);
}
}
}
void save(){
struct citizen s[50];
FILE *f;
f=fopen("detyra_day.dat","w");
if (f==NULL){
printf("\n Error on the file");
return;
}
for(int i=0;i<nr_people; i++){
fwrite(&s[i],sizeof(struct citizen),1,f);
}
}
int main(){
char selection;
do{
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------");
printf("\n Zgjedhja : ");
selection=getch();
switch(selection){
case '1':
readPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
case '9':
exit(0);
}
getch();
} while(selection!='9');
return 0;
}
在我按下运行并尝试读取并打印数字 1 后,它将每个人打印为 1,而不是像结构所说的那样。例如我想像这样打印它:
IDNR: H65328040Q
Name: Azbie
Lname: Gockaj
Birthday (YYYYMMDD format):19760328
ID_Family: 1
相反,我得到:
INDR: Name: Lname: Birthday: ID_Family:
然后每个人都订购
H65328040Q Azbie Gockaj 19760328 1
J70507042S Ledion Celaj 19970507 1
G70312202S Pellumb Osmani 19670312 2
H45827189P Albina Osmani 19740827 2
解决方案
有许多错误。
首先,您需要一个全局数组,struct citizen
而不是在每个函数中都有一个作用域struct citizen
的函数。
在struct citizen
中,idNr
太小而无法包含 10 位数的 ID 号。它必须 [至少] 多一个才能说明字符串末尾的 EOS 字符。
使用fread
和fwrite
访问数据文件。它们用于二进制文件,但您有一个文本文件。您需要分别使用fscanf
和fprintf
。
使用(例如) [function scoped] char *name;
。这是一个指向char
[array/string] 的指针,它是uninitialized。将此更改为char name[100];
使用strstr
而不是strcmp
.
使用scanf
或fscanf
不一致。如果您编译时-Wall -Wextra
启用警告 [ gcc
],它们就会变得明显。
getch
混合[ fgetc
] 和scanf
在同一个流上是不好的做法。
为了保持一致性,我添加了一个函数而不是用于提示用户prompt
的各种序列。printf(...); scanf(...);
你并没有真正struct birthday
在代码中使用你的。
这是清理后的代码。一些基础知识已经过测试,但仍有一些我无法解决的问题。在大多数地方,我习惯于#if 0
表示您的旧代码 [vs. 我的新代码]
#include <stdio.h>
#include <string.h>
#ifndef __linux__
#include <conio.h>
#include <dos.h>
#endif
#include <windows.h>
#ifdef __linux__
#include <time.h>
int
getch(void)
{
char buf[1000];
int chr;
if (fgets(buf,sizeof(buf),stdin) != 0)
chr = buf[0];
else
chr = -1;
return chr;
}
WINBASEAPI VOID WINAPI
GetLocalTime(LPSYSTEMTIME lps)
{
time_t tod;
struct tm *tm;
tod = time(NULL);
tm = localtime(&tod);
lps->wYear = tm->tm_year + 1900;
lps->wMonth = tm->tm_mon + 1;
lps->wDayOfWeek = tm->tm_wday;
lps->wDay = tm->tm_mday;
lps->wHour = tm->tm_hour;
lps->wMinute = tm->tm_min;
lps->wSecond = tm->tm_sec;
lps->wMilliseconds = 0;
}
#endif
int permission;
int hour;
int minute;
int nr_people;
struct birthday {
int year;
int month;
int day;
};
struct citizen {
#if 0
char idnr[10];
#else
char idnr[10 + 1];
#endif
char name[50];
char lname[50];
struct birthday birthday;
int id_family;
};
#define CITMAX 50
struct citizen citlist[CITMAX];
char fname[] = { "detyra_day.dat" };
void
prompt(const char *str,char *buf)
{
printf("%s: ",str);
fflush(stdout);
fgets(buf,100,stdin);
char *cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
}
void
getbday(const char *buf,struct birthday *bday)
{
sscanf(buf,"%4d%2d%2d",&bday->year,&bday->month,&bday->day);
}
void
loadPeopleInfo()
{
struct citizen *s;
char birthday[100];
FILE *f;
nr_people = 0;
f = fopen(fname, "r");
if (f == NULL) {
printf("Error opening file\n");
exit(1);
}
while (1) {
s = &citlist[nr_people];
if (fscanf(f," %s %s %s %s %d\n",
s->idnr,s->name,s->lname,birthday,&s->id_family) != 5)
break;
getbday(birthday,&s->birthday);
nr_people++;
if (nr_people >= CITMAX)
break;
}
fclose(f);
}
void
printPeopleInfo()
{
struct citizen *s;
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\t\tname\tlname\tbirthday\tid_family\n\n");
for (int i = 0; i < nr_people; ++i) {
s = &citlist[i];
printf("%s\t", s->idnr);
printf("%s\t", s->name);
printf("%s\t", s->lname);
struct birthday *bday = &s->birthday;
printf("%4.4d%2.2d%2.2d\t",bday->year,bday->month,bday->day);
printf("%d\t\n", s->id_family);
}
printf("========================================================\n\n");
printf("Number of citizen = %d\n", nr_people);
}
void
add()
{
#if 0
struct citizen s, s1;
#else
struct citizen *s;
struct citizen s1;
#endif
#if 0
int nr_people = 5;
#endif
int found = 0;
char buf[100];
#if 0
printf("\n Give the unique IDNR: ");
scanf("%s\n", &s1.idnr);
#else
prompt("Give the unique IDNR",s1.idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
#if 0
if (s1.idnr == s->idnr) {
#else
if (strcmp(s1.idnr,s->idnr) == 0) {
printf("The citizen with this IDNR exist\n");
found = 1;
return;
}
#endif
}
if (found == 0) {
s = &citlist[nr_people];
printf("The citizen with this IDNR doesn't 'exist\n");
strcpy(s->idnr, s1.idnr);
#if 0
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
#else
prompt("Give the name of the citizen",s->name);
#endif
#if 0
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
#else
prompt("Give the lname of the citizen",s->lname);
#endif
#if 0
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n",buf);
#else
prompt("Give the birthday of the citizen in the format YYYYMMDD",buf);
#endif
getbday(buf,&s->birthday);
#if 0
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
#else
prompt("Give the ID of the family of the citizen",buf);
sscanf(buf,"%d", &s->id_family);
#endif
nr_people++;
}
}
void
change()
{
struct citizen *s;
char birthday[100];
#if 0
char *idnr;
#else
char idnr[100];
#endif
printf("\n IDNR of citizen: ");
#if 0
scanf("%s", &idnr);
#else
scanf("%s\n",idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (strcmp(s->idnr, idnr) == 0) {
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n", birthday);
getbday(birthday,&s->birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
printf("\n Changed succesfully.");
return;
}
#if 0
printf("\n The change didn't happened.");
#endif
}
#if 1
printf("\n The change didn't happened.");
#endif
}
void
permit()
{
#if 0
struct birthday bday;
#else
struct birthday *bday;
#endif
struct citizen *s;
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
bday = &s->birthday;
if (bday->month > d.wMonth ||
(bday->month == d.wMonth && bday->day >= d.wDay)) {
age[i] = d.wYear - bday->year;
}
else {
age[i] = d.wYear - bday->year - 1;
}
}
#if 0
char *name;
char *lname;
char *chosenperson;
#else
char name[100];
char lname[100];
char chosenperson[100];
#endif
int id_family;
int i;
int apply = 0;
int familymembers = 0;
#if 0
printf("Put your name: ");
scanf("%s", &name);
#else
prompt("Put your name",name);
#endif
#if 0
printf("Put your lname: ");
scanf("%s", &lname);
#else
prompt("Put your lname",lname);
#endif
// NOTE/BUG: use strcmp instead of strstr
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if ((strcmp(name, s->name) == 0 && strcmp(lname, s->lname) == 0 &&
age[i] >= 18)) {
printf("Your name is on the list and you are in the age to apply [%d]\n",age[i]);
id_family = s->id_family;
apply = 1;
}
}
if (apply == 0) {
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp[nr_people];
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if (id_family == s->id_family) {
tmp[familymembers++] = *s;
}
}
for (i = 0; i < familymembers; i++) {
printf("%d. name: %10s\n", i + 1, tmp[i].name);
}
apply = 0;
prompt("Give the name of the person from your family that you want to apply ",chosenperson);
printf("\nYou chose: ");
for (i = 0; i < familymembers; i++) {
if (strcmp(chosenperson, tmp[i].name) == 0) {
printf("%s", tmp[i].name);
apply = 1;
}
}
if (apply == 0) {
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f", &timez);
if (timez >= 8.00 && timez <= 17.00) {
hour = timez;
minute = (timez - hour) * 100;
if (minute > 59) {
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",
timez, timez + 2);
permission = 1;
}
else {
printf("You have chosen the wrong time");
return;
}
}
void
control()
{
permit();
SYSTEMTIME d;
struct citizen *s;
GetLocalTime(&d);
int g = permission;
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (g == 1) {
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",
s->idnr, d.wYear, d.wMonth, d.wDay, hour, minute);
}
}
}
void
save()
{
struct citizen *s;
struct birthday *bday;
FILE *f;
f = fopen("detyra_day.dat", "w");
if (f == NULL) {
printf("\n Error on the file");
return;
}
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
fprintf(f,"%s ", s->idnr);
fprintf(f,"%s ", s->name);
fprintf(f,"%s ", s->lname);
bday = &s->birthday;
fprintf(f,"%4.4d%2.2d%2.2d ",bday->year,bday->month,bday->day);
fprintf(f,"%d\n", s->id_family);
}
#if 1
fclose(f);
#endif
}
int
main()
{
char buf[100];
int selection = 0;
loadPeopleInfo();
do {
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------\n");
prompt("Zgjedhja",buf);
selection = buf[0];
switch (selection) {
case '1':
printPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
#if 0
case '9':
exit(0);
#endif
}
#if 0
getch();
#endif
} while (selection != '9');
return 0;
}
推荐阅读
- angular - 用角度的openlayers绘制线串时出错
- go - 找不到包“google.golang.org/protobuf/cmd/protoc-gen-go”
- macos - MacOS QT 中的错误消息“OpenCV:未授权捕获视频(状态 0)”
- angular - 是否可以在运行时在运行的 Angular 解决方案中包含模块?
- sql - 同一查询中的多个计数
- angular - Render is not able to changed the color of back ground
- .net-core - 使用 MethodDecorator.Fody 时如何注入依赖项
- typescript - SyntaxError:使用 jest 和 parcel 时出现意外的标记“<”
- forms - VeeValidate 表单不会运行提交表单功能
- file - 如何在两个android ios的文件管理器中隐藏文件或内容