从循环C中的文本文件中读取数据

时间:2012-11-29 09:07:44

标签: c data-structures text-files

我被要求实施具有以下规格的日历

  • 向日历添加活动
  • 显示特定日历日期的事件。
  • 显示整个日历。
  • 从日历中删除活动。
  • 将日历的事件写入文本文件。
  • 从文本文件中读取日历的事件。

我在从文本文件中读取数据时遇到问题。我的语法正确。但是,我的程序在从文本文件中读取事件时崩溃,并且正好在for循环中。 (请注意ReadfromText函数中有一些调试语句) 这是代码:

        /************************************************************************************************
    Input file: None
    Output file: None
    Description: This calendar program is mainly a menu interactive program that prompts
                 the user for a date and its events, then the entry is stored in its appropriate
                 place inside an array of structures.
                 This program handles 5 main operations:
                    . Add an event to the calendar.
                    . Display events for a specific calendar date.
                    . Display the whole calendar.
                    . Delete the event from the calendar.
                    . Writes the events of a calendar to a text file.
                    . Reads the events of a calendar from a text file.
    ************************************************************************************************/


    #include <stdio.h>
    #include <string.h>
    #include<time.h>
    #define MAXEVS 100   // Defining the maximum number of events as being 100
    typedef enum {FALSE = 0, TRUE = 1} BOOLEAN;
    typedef struct {
        int hours,
            minutes,
            seconds;
    } tm_t;

    typedef struct {
        char month [20];
        int day,
            year; 
    } date_t;

    typedef struct {
        char ev_name [40];
        date_t dt;
        tm_t tm;
    } event_t;

    typedef struct {
        BOOLEAN valid;
        event_t event_list [MAXEVS];
        int num_events;
    } calentry_t; 

        int counter = 0; //Global counter variable used to keep track of number of events
        void menu (); // This function displays the menu to the user 
        void InitializeCalender(calentry_t calendar[][31]  ); // Initializes the calendar for valid and invalid dates
        int ReadEvent ( calentry_t calendar[][31],char eventname[], char month[], int *day, int *year, int *h, int *min); // This function min role is to get the input from the user (the whole calendar entry)
        int MonthStr2Num ( char* month); // This function converts a string containing a month to its appropriate number
        void AddEvent (calentry_t calendar[][31], char eventname[], int* monthnum, int *day, int *year, int *h, int *min); // This function places the calendar entry places the event inside its appropriate place inside the 2D array
        char* MonthNum2Str (int* m); // Converts a number to its appropriate month
        void DisplayCalendar (calentry_t calendar[][31], int* monthnum, int* day, int* year); // Displays the calendar entry for a specific date
        void DisplayWholeCalendar ( calentry_t calendar[][31]); // This function displays the whole entries stored inside the calendar
        int DeleteEvent (calentry_t calendar [][31]); // This function deletes an event from the calendar
        void SavetoText (calentry_t calendar [][31], FILE* fp, time_t tt);
        void ReadfromText(calentry_t calendar [][31],char eventname[], int* monthnum, int *day, int *year, int *h, int *min, FILE* fp);
    main (){
        time_t t = time(NULL);
        FILE *fp;

        int choice;
        calentry_t calendar[12][31]; // Declaring a 2D array of structure calentry_t
        calentry_t calendarf[12][31]; // Declaring a 2D array of structure calentry_t

        char eventname [100];
        char month[20];
        int day, year, h, min, monthnum;
        char temp;

        InitializeCalender(calendar);
        InitializeCalender(calendarf);
        do{ // loop that continues to execute the program until the user decides to quit
        menu ();

        scanf ("%d",&choice);
        switch (choice)
        {
            case 0:
            printf("Calendar will now quit.\n");
            break;
            case 1:
            monthnum = ReadEvent(calendar ,eventname, month, &day, &year, &h, &min);
            AddEvent (calendar, eventname, &monthnum, &day, &year, &h, &min);
            break;
            case 2:
            printf ("What is the date that you want to display its events? input like ( 12 January 2012 ) ");
            scanf ("%d %s %d", &day, month, &year);
            monthnum = MonthStr2Num (month); 
            DisplayCalendar (calendar ,&monthnum, &day, &year);
            break;
            case 3:
            printf ("The whole calendar will be displayed immediately\n");
            DisplayWholeCalendar (calendar);
            break;
            case 4: 
            DeleteEvent (calendar);
            break;
            case 5:
            SavetoText (calendar, fp, t);
            break;
            case 6:
            ReadfromText (calendarf, eventname, &monthnum, &day, &year, &h, &min, fp);
            break;
        }
        }
        while (choice !=0);
    } //End of the main function

    void menu ()
    {
        printf("___________________________________________________________________________\n");
        printf("\tHere is the menu:\n");
        printf("\t0. Quit the Program.\n");
        printf("\t1. Add an event to the calendar.\n");
        printf("\t2. Display events for a specific calendar date.\n");
        printf("\t3. Display the whole calendar.\n");
        printf("\t4. Delete the event from the calendar.\n");
        printf("\t5. Save the calendar to a text file.\n");
        printf("\t6. Read the calendar from a text file.\n"); 
        printf("____________________________________________________________________________\n");
        printf("\tYour choice Please: ");
    }

    void InitializeCalender(calentry_t calendar[][31]){
    int x, y;
        for(x = 0; x < 12; x ++) {
            if (x==1){
                for(y = 0; y < 28; y ++){ 
                    (calendar[x][y]).valid = TRUE;
                    (calendar[x][y]).num_events = FALSE;
                }
                for (y=28; y< 31; y++){
                    (calendar[x][y]).valid = FALSE;
                }
            }
            else if  (x==3 || x==5 || x==8 || x==10){
                for(y = 0; y < 30; y ++){ 
                    (calendar[x][y]).valid = TRUE;
                    (calendar[x][y]).num_events = FALSE;

                }
                for (y=30; y< 31; y++){
                    (calendar[x][y]).valid = FALSE;
                }
            }
            else if (x==0 || x==2||x==4||x==6||x==7||x==9||x==11){
                for(y = 0; y < 31; y ++){ 
                    (calendar[x][y]).valid = TRUE;
                    (calendar[x][y]).num_events = FALSE;
                }
            }
        }
    }

    int ReadEvent (calentry_t calendar[][31] ,char eventname[], char month[], int *day, int *year, int *h, int *min){

        char temp, answer;
        int monthnum;

            printf ("\n\tOkay, for event number %d:\n",counter+1 );
            printf ("\n\tWhat is the name of the event? ");
            scanf ("%c",&temp);
            gets (eventname);

            printf("\n\twhat is the date of the event? input like ( 12 January 2012 ) ");   
            scanf ("%d %s %d", day, month, year);
            monthnum = MonthStr2Num (month);
                if ( calendar [(monthnum-1)][(*day-1)]. valid ==FALSE || *day>=32 ){
                    while ( calendar [(monthnum-1)][(*day-1)]. valid ==FALSE || *day>=32 ) { //Loop that checks invalid dates
                    printf ("\tSorry that'san invalid date!!!!!\n");
                    printf("\n\twhat is the date of the event? input like ( 12 January 2012 ) ");   
                    scanf ("%d %s %d", day, month, year);
                    monthnum = MonthStr2Num (month);
                    } 
                }


            printf ("\n\tWhat is the time of the event? input like (12:30) ");
            scanf ("%d:%d", h,min);
                if ( *h>=24 || *h<0 || *min>=60 || *min<0){ //Loop that checks invalid times
                    while ( *h>=24 || *h<0 || *min>=60 || *min<0){
                        printf ("\tInvalid Time !!!!! \n");
                        printf ("\n\tWhat is the time of the event? input like (12:30) ");
                        scanf ("%d:%d", h,min);
                    }
                }
            monthnum = MonthStr2Num (month);
            return monthnum;

    }
    int MonthStr2Num ( char* month){
            int i,
                m=0;
        // Converting all the month characters to uppercase in order to handle all the cases of how the user 
        // enters the month
        for(i=0;i<=strlen(month);i++)
        {
        if(month[i]>=97&&month[i]<=122)
        month[i]=month[i]-32;
        }

        if (strcmp((month), "JANUARY")==0){ 

            m = 1;}

        else if (strcmp((month), "FEBRUARY")==0)
        m = 2;
        else if (strcmp((month), "MARCH")==0)
        m = 3;
        else if (strcmp((month), "APRIL")==0)
        m = 4;
        else if (strcmp((month), "MAY")==0)
        m = 5;
        else if (strcmp((month), "JUNE")==0)
        m = 6;
        else if (strcmp((month), "JULY")==0)
        m = 7;
        else if (strcmp((month), "AUGUST")==0)
        m = 8;
        else if (strcmp((month), "SEPTEMBER")==0)
        m = 9;
        else if (strcmp((month), "OCTOBER")==0)
        m = 10;
        else if (strcmp((month), "NOVEMBER")==0)
        m = 11;
        else if (strcmp((month), "DECEMBER")==0)
        m = 12;
        return m;
    }

    void AddEvent (calentry_t calendar[][31], char eventname[], int* monthnum, int *day, int *year, int *h, int *min){
        char monthstr [20];
        strcpy(monthstr,MonthNum2Str(monthnum));
        strcpy ( calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].ev_name,eventname );
        strcpy ( calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].dt.month,monthstr );  
        calendar [(*monthnum-1)][(*day-1)].num_events++;
        calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].dt.day = (*day);
        calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].dt.year = (*year); 
        calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].tm.hours = (*h);
        calendar [(*monthnum-1)][(*day-1)]. event_list[calendar[(*monthnum-1)][(*day-1)].num_events].tm.minutes = (*min);           
        counter++;

    }

    char* MonthNum2Str (int* m){ 
        if (*m==1)
        return "January";
        else if (*m==2)
        return "February";
        else if (*m==3)
        return "March";
        else if (*m==4)
        return "April";
        else if (*m==5)
        return "May";
        else if (*m==6)
        return "June";
        else if (*m==7)
        return "July";
        else if (*m==8)
        return "August";
        else if (*m==9)
        return "September";
        else if (*m==10)
        return "October";
        else if (*m==11)
        return "November";
        else if (*m==12)
        return "December";
    }

    void DisplayCalendar (calentry_t calendar[][31], int* monthnum, int* day, int* year){
        int i;

        if ( calendar [(*monthnum-1)][(*day-1)].num_events==0)
            printf ("\n\tNo events on this date!!!!!!\n");
            else{
            printf ("\n\tOn %d-%s-%d You have %d event(s): \n", *day, calendar [(*monthnum-1)][(*day-1)]. event_list[(calendar[(*monthnum-1)][(*day-1)].num_events)-1].dt.month, *year, calendar[(*monthnum-1)][(*day-1)].num_events);
                for (i=0; i<calendar[(*monthnum-1)][(*day-1)].num_events; i++){
                    printf ("\t\n Event %d: ", i+1);
                    printf ("\t\n Name of the event: %s", calendar [(*monthnum-1)][(*day-1)]. event_list[i].ev_name );
                    printf ("\t\n Time of the event: %d:%d\n", calendar [(*monthnum-1)][(*day-1)]. event_list[i+1].tm.hours, calendar [(*monthnum-1)][(*day-1)]. event_list[i+1].tm.minutes);
                }
            }
    }

    void DisplayWholeCalendar ( calentry_t calendar[][31]){
        int x, y, i;

        printf ("You have a total of %d event(s)\n", counter);

        for(x = 0; x < 12; x ++) {
            for (y=0; y< 31; y++){
                if ((calendar[x][y]).valid == FALSE ||(calendar[x][y]).num_events == FALSE){
                }
                else {
                printf ("On %d-%s-%d You have %d event(s): \n", y+1, calendar [x][y]. event_list[(calendar[x][y].num_events)-1].dt.month, calendar [x][y]. event_list[calendar[x][y].num_events].dt.year, calendar[x][y].num_events);
                    for (i=0; i<calendar[x][y].num_events; i++){
                    printf ("\t\n Event %d: ", i+1);
                    printf ("\t\n Name of the event: %s", calendar [x][y]. event_list[i].ev_name );
                    printf ("\t\n Time of the event: %d:%d\n", calendar [x][y]. event_list[i+1].tm.hours, calendar [x][y]. event_list[i+1].tm.minutes);
                    }
                }
            }
        }
    }

    int DeleteEvent (calentry_t calendar [][31]){
        int day, year, monthnum, choice, c;
        char month [20];

        printf ("\n\tWhat is the date that you want to delete one of its events? input like ( 12 January 2012 )  ");
        scanf ("%d %s %d", &day, month, &year);
        monthnum = MonthStr2Num (month);
        if ( calendar [(monthnum-1)][(day-1)].num_events==0){
            printf ("No events on this date!!!!!!\n");
            return 0;
        }
        if ((calendar[(monthnum-1)][(day-1)]).valid == FALSE){
            printf ("Invalid date !!!!\n");
            return 0;
        }
        else {
        DisplayCalendar (calendar ,&monthnum, &day, &year);
        printf ("\n\nWhat is the event that you want to delete (press 1 for event 1 or 2 for event 2...) ");
        scanf ("%d", &choice);
            if ( choice >= (calendar [(monthnum-1)][(day-1)].num_events)+1 )
                 printf("\n\tDeletion not possible.\n");

            else {
                for ( c = choice - 1 ; c < (calendar [monthnum-1][day-1].num_events) ; c++ ){
              calendar [monthnum-1][day-1]. event_list[c] =calendar [monthnum-1][day-1]. event_list[c+1];   
                }         calendar [monthnum-1][day-1].num_events--;
                            printf ("\n\tEvent deleted \n");
                            counter--;
            }
        }


    }

    void SavetoText (calentry_t calendar [][31], FILE* fp, time_t tt)
    {
        char buf[80];
        struct tm* st = localtime(&tt);
        strftime(buf, 80, "eventlog_%d-%B-%y_%H.%M.txt", st);
            fp= fopen (buf, "w");
            if (fp== NULL)
            printf ("\tError! File could not be opened\n");
            else
            {
            int x, y, i;

        for(x = 0; x < 12; x ++) {
            for (y=0; y< 31; y++){
                if ((calendar[x][y]).valid == FALSE ||(calendar[x][y]).num_events == FALSE){
                }
                else {
                        fprintf (fp, "%d %s %d\n",y+1,calendar [x][y]. event_list[(calendar[x][y].num_events)-1].dt.month, calendar [x][y]. event_list[calendar[x][y].num_events].dt.year);

                        fprintf (fp, "%d\n", calendar[x][y].num_events );
                    for (i=0; i<calendar[x][y].num_events; i++){
                        fprintf (fp, "%s %d %d\n", calendar [x][y]. event_list[i].ev_name , calendar [x][y]. event_list[i+1].tm.hours,calendar [x][y]. event_list[i+1].tm.minutes);
                    }
                }
            }
        }   
     }
     printf ("\tEvents were printed in the textfile file successfully!\n");
     fclose (fp); 
    }

    void ReadfromText(calentry_t calendar [][31],char eventname[], int* monthnum, int *day, int *year, int *h, int *min,  FILE* fp)
    {   
        char filename [20];
        char month[20];
        int numevents, i;
        printf ("\n\tWhat is the name of the file that you want to open (input like: eventlog_29-November-12_1.22.txt): ");
        scanf ("%s", &filename);
        fp= fopen (filename, "r");
        if (fp==NULL)
        printf ("\tError! File could not be opened\n");
        else 
        {
            while (!feof(fp))
            {
                fscanf (fp, "%d %s %d\n",  &day, month, &year);
                fscanf (fp, "%d\n", &numevents);
                (*monthnum) = MonthStr2Num (month);
                printf ("The month number is %d", (*monthnum));
                printf ("The number of events is %d\n", numevents);
                    for (i=0; i<numevents; i++)
                    {   printf ("I am inside the loop\n");
                        fscanf (fp, "%s %d %d\n", eventname , &h, &min);
                        printf ("%s %d %d\n", eventname , h, min);
                        AddEvent (calendar, eventname, monthnum, day, year, h, min); 
                        printf ("Added to the calendar\n");
                    }

            }
        }
        DisplayWholeCalendar (calendar);    
    }

有人可以帮忙吗?提前谢谢

2 个答案:

答案 0 :(得分:1)

将功能声明更改为

void ReadfromText(calentry_t calendar [][31],char eventname[], int* monthnum, int day, int year, int h, int min, FILE* fp);

将其命名为:

case 6:
ReadfromText (calendarf, eventname, &monthnum, day, year, h, min, fp);

ReadFromText内,将AddEvent称为

printf ("%s %d %d\n", eventname , h, min);
AddEvent (calendar, eventname, monthnum, &day, &year, &h, &min); 
printf ("Added to the calendar\n");

ReadFromText内进行此更改

fscanf (fp, "%d %s %d\n",  &day, month, &year);

答案 1 :(得分:0)

嗯,ReadFromText()函数的一些或多或少的明显问题是:

  1. 不要那样使用feof();它的返回值无效,直到 之后你才尝试读取失败。
  2. 检查fscanf()的返回值以确保其成功,依赖输出之前。
  3. 奇怪的是你传入fp,然后在函数内部覆盖它,但我没有追溯到函数中,看看这可能意味着什么。