Почему моя программа продолжает печатать значения мусора? - PullRequest
0 голосов
/ 27 марта 2019

По какой-то причине, когда я ввожу свое время, описание и индекс и нажимаю quit, чтобы напечатать массив, который я заполнил значениями и строками, я получаю кучу мусорных значений вместо того, что я ввел, не уверен, что я делаю неправильно. любой совет?

По какой-то причине, когда я ввожу свое время, описание и индекс и нажимаю quit, чтобы напечатать массив, который я заполнил значениями и строками, я получаю кучу мусорных значений вместо того, что я ввел, не уверен, что я делаю неправильно. любой совет?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5

struct event    //data type called event which holds time and description for events
{
    int hour; //holds the hour digit between 0-23
    int minute; //holds the minute digit between 0-59
    char description[41];
//holds the description for the reason of the alarm
};

typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"

int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
int AddEventAtIndex(Event list[], Event e, int i);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);

int main (void)
{
    Event EventList[MAX];
    Event e;
    int i=0;
    int eventListSize = 0;
    int choice;

    do
    {

        printf("__= Scheduler v1.0 =__\n");
        printf("1. Schedule an event.\n");
        printf("2. Delete an event.\n");
        printf("3. Display schedule.\n");
        printf("4. Save schedule.\n");
        printf("5. Load schedule.\n");
        printf("6. Exit\n");

        switch(choice = InputRange(1, 6))
        {

            case 1: InputEvent( EventList );
                i = AddEventAtIndex(EventList, e, i);
                break;
        /*  case 2: pHead = deleteStudent(pHead);
                break;
            case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
                scanf("%d", &search);
                if (search == 1){
                    searchStudentID(pHead);
                }
                else if (search == 2){
                    searchStudentlName(pHead);
                }
                else{
                    printf("Invalid selection");
                }
                break;
            case 4: displayStudentInfo(pHead);
                break;
            case 5: saveStudentInfo(pHead);
                break;
            case 6: end(pHead);
                break;*/
        default: printf("Exiting Program\n\n");
        }
    }
    while ( choice != 6 );

    printf("Index #[]\tTime\tDescription");

    for ( int j = 1; j < 6; j++)
    {
        printf("\n[%d]\n\t%d:%d \t %s", j, EventList[j].hour,
               EventList[j].minute, EventList[j].description);
    }
}

int InputRange(int min, int max)
{
    int timenumber;

    printf("Please enter a number between %d - %d\n", min, max);
    scanf("%d", &timenumber);
    printf("\n");

    if (timenumber < min || timenumber > max)
    {
        printf("Invalid Entry\n");
        InputRange(min, max);
    }
    return timenumber;
}

Event* InputEvent(Event *newEvent)
{
    if (newEvent != NULL) // quality assurance:
        // make sure the pointer is valid
        {
            printf("Enter the event time:\n");
            newEvent->hour = InputRange(0, 23);
            newEvent->minute = InputRange(0, 59);
            printf("Enter the event description:\n");
            fgetc(stdin);
            fgets(newEvent->description, 41, stdin);
            printf("\n");
        }
        return newEvent;
}

int AddEventAtIndex(Event list[], Event e, int i)
{
    --i;

    printf("Where in the array would you like to store this event\n");
    i = InputRange(1, 5);
    list[i].hour = e.hour;
    list[i].minute = e.minute;
    strcpy(list[i].description, e.description);

    return i;
}

1 Ответ

2 голосов
/ 27 марта 2019

Почему моя программа продолжает печатать значения мусора?

Вы используете неинициализированные данные, в main у вас есть:

  Event e;
  ...
  i = AddEventAtIndex(EventList, e, i);

, где e не инициализируется, но используется в AddEventAtIndex :

int AddEventAtIndex(Event list[], Event e, int i)
{
  ...
  list[i].hour = e.hour;
  list[i].minute = e.minute;
  strcpy(list[i].description, e.description);

в поведении strcpy с неинициализированным значением не определено и может иметь драматические последствия.

Возможно, вызов InputEvent( EventList ); должен быть заменен на InputEvent(&e);

In

for ( int j = 1 ; j < 6 ; j++)
{
  printf("\n[%d]\n\t%d:%d \t %s", j, EventList[j].hour, 
         EventList[j].minute, EventList[j].description);
}

Вы получаете доступ из EventList , когда j равно 5 и 6, сделайте, например:

 for ( int j = 0 ; j < MAX ; j++)
 {
   printf("[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour, 
          EventList[j].minute, EventList[j].description);
 }

Но вы также пишете записи, никогда не устанавливая печатные значения мусора«Более того, факт печати строки без инициализации имеет неопределенный эффект.Способ разделения записей, установленных и не установленных, состоит в том, чтобы инициализировать все часы на 24 и проверить это значение в цикле, чтобы записать или нет запись.

Я также изменил формат, потому что символ новой строки после индексанесовместимо с printf("Index #[]\tTime\tDescription");, и лучше поставить другую новую строку после все вместо до , чтобы очистить строку вывода, поэтому также измените printf("Index #[]\tTime\tDescription"); на puts("Index #[]\tTime\tDescription");

MAX не очень хорошее имя, потому что это больше SUP, или просто переименуйте его по РАЗМЕРУ

В main вы не используете eventListSize


In AddEventAtIndex

--i должно быть сделано после i = InputRange(1, 5); или просто сделать i = InputRange(1, 5) - 1;иначе, когда i значений 5 list[i] выходит за пределы списка , поэтому вы записываете из списка с неопределенным поведением.

Итак, наконецпараметр i бесполезен, удалите его.

Индекс возврата также не используется в main , вы используете его для присвоения i и не использовать значение i после. AddEventAtIndex не нужно возвращать значение.


In InputRange

Вы не проверяете результат scanf поэтому значение номер_иммера не определено, если было введено недопустимое целое число и если вы не удаляете ввод, поэтому все следующие scanf для получения числа не будут успешными

Кроме того, если значение не находится в диапазоне, вы просто вызываете InputRange(min, max);, не возвращая его значение, поэтому, в конце концов, вы возвращаете недопустимое значение, поместите все в for(;;), например, для возврата только тогда, когда значение верное.

Вы используете fgets в InputEvent , чтобы смешать его с scanf , чтобы прочитать число - источник проблемы, замените scanf с помощью fgets , затем sscanf в строке чтения


In InputEvent

Когдавы делаете fgetc(stdin); вы, вероятно, надеетесь обойти новую строку, но если пользователь вводит символы после числа в InputRange (предположим, что число было введено) fgets прочитает первый из них, а fgets не получит ожидаемое описание.Решение состоит в том, чтобы сделать fgets затем sscanf в InputRange , как я уже говорил выше, что позволит вам удалить fgetc


Предложение с учетом моих замечаний:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 5

struct event    //data type called event which holds time and description for events
{
  int hour;   //holds the hour digit between 0-23
  int minute; //holds the minute digit between 0-59
  char description[41];  //holds the description for the reason of the alarm
};

typedef struct event Event; //allows coder to only have to use "Event" instead of "struct event"

int InputRange(int min, int max);
Event* InputEvent(Event *newEvent);
void AddEventAtIndex(Event list[], Event e);
//int InsertionSortEvent(Event list[], int *p_size, Event e);
//void DisplayEvent(Event e);
//void DisplayEventList(Event list[], int size);
//int DeleteEvent(Event list[], int i, int *p_size);

int main (void)
{
  Event EventList[MAX];
  Event e;
  int choice;

  /* mark uset entries */
  for (int i = 0; i != MAX; ++i)
    EventList[i].hour = 24;

  do
  {
    printf("__= Scheduler v1.0 =__\n");
    printf("1. Schedule an event.\n");
    printf("2. Delete an event.\n");
    printf("3. Display schedule.\n");
    printf("4. Save schedule.\n");
    printf("5. Load schedule.\n");
    printf("6. Exit\n");

    switch(choice = InputRange(1, 6))
    {
      case 1: 
        InputEvent( &e );
        AddEventAtIndex(EventList, e);
        break;
      /*case 2: pHead = deleteStudent(pHead); 
                    break;
        case 3: printf("Press 1 to search by ID or 2 to search by name: \n");
                    scanf("%d", &search);
                    if (search == 1){
                        searchStudentID(pHead); 
                    }
                    else if (search == 2){
                        searchStudentlName(pHead);
                    }
                    else{
                        printf("Invalid selection");
                    }
                    break;
        case 4: displayStudentInfo(pHead);
                    break;
        case 5: saveStudentInfo(pHead);
                    break;
        case 6: end(pHead);
                    break;*/
      default: printf("Exiting Program\n\n");
    }
  }
  while ( choice != 6 );

  puts("Index #[]\tTime\tDescription");

  for ( int j = 0 ; j < MAX ; j++)
  {
    if (EventList[j].hour != 24)
      printf("\t[%d]\t%d:%d \t %s\n", j+1, EventList[j].hour, 
             EventList[j].minute, EventList[j].description);
  }
}

int InputRange(int min, int max)
{
  char line[32];
  int timenumber;

  for (;;) {
    printf("Please enter a number between %d - %d\n", min, max);
    if (fgets(line, sizeof(line), stdin) == NULL)
      /* EOF */
      exit(-1);
    if ((sscanf(line, "%d", &timenumber) == 1) &&
        (timenumber >= min) &&
        (timenumber <= max))
      return timenumber;

    printf("Invalid Entry\n");
  }
}

Event* InputEvent(Event *newEvent)
{   
  if (newEvent != NULL)   // quality assurance:
    // make sure the pointer is valid
  {
    printf("Enter the event time:\n");
    newEvent->hour = InputRange(0, 23);
    newEvent->minute = InputRange(0, 59);
    printf("Enter the event description:\n");
    fgets(newEvent->description, sizeof(newEvent->description), stdin);
    printf("\n");
  }
  return newEvent;
}

void AddEventAtIndex(Event list[], Event e)
{
  printf("Where in the array would you like to store this event\n");

  int i = InputRange(1, 5) - 1;

  list[i].hour = e.hour;
  list[i].minute = e.minute;
  strcpy(list[i].description, e.description);
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall c.c
pi@raspberrypi:/tmp $ ./a.out
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
2
Please enter a number between 0 - 59
22
Enter the event description:
descr1

Where in the array would you like to store this event
Please enter a number between 1 - 5
1
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
1
Enter the event time:
Please enter a number between 0 - 23
3
Please enter a number between 0 - 59
33
Enter the event description:
descr2

Where in the array would you like to store this event
Please enter a number between 1 - 5
4
__= Scheduler v1.0 =__
1. Schedule an event.
2. Delete an event.
3. Display schedule.
4. Save schedule.
5. Load schedule.
6. Exit
Please enter a number between 1 - 6
12
Invalid Entry
Please enter a number between 1 - 6
6
Exiting Program

Index #[]   Time    Description
    [1] 2:22     descr1

    [4] 3:33     descr2

обратите внимание на пустую строку в окончательном варианте, это потому, что новая строка является частьюописание, которое необходимо удалить присутствует в InputEvent

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...