首页 > 解决方案 > 在我使用文件从结构打印后,它不起作用

问题描述

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:

然后每个人都订购

这是 detyra_day.dat 文件

H65328040Q Azbie Gockaj 19760328 1

J70507042S Ledion Celaj 19970507 1

G70312202S Pellumb Osmani 19670312 2

H45827189P Albina Osmani 19740827 2

标签: cfilestructprintf

解决方案


有许多错误。

首先,您需要一个全局数组,struct citizen而不是在每个函数中都有一个作用域struct citizen的函数。

struct citizen中,idNr太小而无法包含 10 位数的 ID 号。它必须 [至少] 多一个才能说明字符串末尾的 EOS 字符。

使用freadfwrite访问数据文件。它们用于二进制文件,但您有一个文本文件。您需要分别使用fscanffprintf

使用(例如) [function scoped] char *name;。这是一个指向char[array/string] 的指针,它是uninitialized。将此更改为char name[100];

使用strstr而不是strcmp.

使用scanffscanf不一致。如果您编译时-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;
}

推荐阅读