Изменение значений на втором уровне многомерного массива во время цикла - PullRequest
0 голосов
/ 23 июня 2019

У меня есть задание hw, которое я хотел бы закончить. Я сделал большую часть этого, но я застреваю в одном месте. У меня есть двумерный цикл строк в C, которые представляют студентов и их оценки.

Моя цель состоит в том, чтобы пользователь мог отображать оценки, а затем обновлять их. Я структурировал массив, чтобы показать имя учеников и оценку в конце после двух пробелов. Мне удалось добраться до точки, где я смог найти студентов в массиве с жестким кодом. Я также дошел до того, что могу выделить последнее значение массива (оценку) и отобразить его. Моя проблема, когда я пытаюсь обновить это значение до нового значения. То, как у меня теперь есть код при замене оценки, перезаписывает все значение вместе с именем ученика.

EDIT: Я хотел обновить, я полагал, что текущий вывод переписывает значение массива учащегося только с обновленной оценкой, но на самом деле это просто обновление первого значения в массиве с обновленным значением оценки.

Я попытался с помощью strcat связать имя учащегося и обновленную оценку. Просто чтобы увидеть, что происходит. Это выглядело как

strcat(updated_grade, student_info[j])

Я попытался поэкспериментировать с использованием разных указателей вместе с моим кодом, но безрезультатно.

int DisplaystudentInformation()
{
  // Welcome Message shows after successful login
  printf("%s\n", "Welcome professor. Below are all student grades");

  // Hard code array to hold student information
  char student_info[5][10] =
  {
    "Jim  A",
    "Tom  C",
    "Ben  C",
    "Alice  D",
    "Ruby  F",
  };

  // Initialize i to use to loop through array
  int i = 0;
  int j = 0;
  int t = 0;
  for (i = 0; i < sizeof(student_info)/sizeof(student_info[0]); i++)
  {
    // Used multiple spaces to get rid of dangling new line
    printf("%s    \n", student_info[i]);
  }

  // Character for reading if faculty wants to adjust grades
  char adjust_grades[2];

  printf("%s", "Adjust grades for students? Please Type y to adjust, or n to exit: ");
  scanf("%s", adjust_grades);

  // Check if adjust grades is Y
  // Using == as the correct assign operator
  if (strcmp(adjust_grades, "y") == 0 || strcmp(adjust_grades, "Y") == 0)
  {
    //Set up vars for adjusting grades
    char student_to_adjust[10];
    char temp_name_input[3];

    // Get name of student
    printf("%s", "Please enter students name: \n");
    scanf("%s", student_to_adjust);

    // Create a temp name to copy the first three letters of a student's name
    strncpy(temp_name_input, student_to_adjust, 3);

    // Terminate null characters manually
    if (strlen(student_to_adjust) == 5 || strlen(student_to_adjust) == 4)
    {
      temp_name_input[strlen(temp_name_input) - 3] = '\0';
    }
    else
    {
      temp_name_input[strlen(temp_name_input) - 3] = '\0';
    }


    // Temp char to serve as copied string, still using the first three letters of the student name
    char temp_student_name[3];

    for (j = 0; j < sizeof(student_info)/sizeof(student_info[0]); j++)
    {

      strncpy(temp_student_name, student_info[j], 3);

      // Found Student and will edit grade
      if(strcmp(temp_student_name, temp_name_input) == 0)
      {
        // Use this to adjust grades
        printf("%s", "\nStudent found. \n");

        // Determine the size of the array and adjust the position of the array spot.
        if (strlen(student_info[j]) == 6)
        {
          printf("\nCurrent Grade: %c \n", student_info[j][5]);

          //New grade character
          char new_grade[1];

          printf("%s", "Enter new grade: \n");
          scanf("%s", new_grade);

          student_info[j][6] =  *new_grade;


          // Show all the students grades along with the updated grade
          for (t = 0; t < sizeof(student_info)/sizeof(student_info[0]); t++)
          {
            printf("%s    \n", student_info[t]);
          }
        }

        break;
      }
    }


  }
  else if (strcmp(adjust_grades, "n") == 0 || strcmp(adjust_grades, "N") == 0) // Option to log out if the user is not adjusting anything
  {
    printf("%s", "\nLogging you out \n");
    exit(0);
  }
  else // Logs out if invalid entry it put in
  {
    printf("%s", "\nInvalid input, logging out. \n");
    exit(0);
  }

}

Я ожидаю что-то вроде:

Jim  A
Tom  C
Ben  C
Alice  D
Ruby  F

Но то, что я сейчас получаю, это:

F
Jim  A
Tom  C
Ben  CF
Alice  D
Ruby  F

1 Ответ

3 голосов
/ 23 июня 2019

У вас есть несколько переполнений буфера, которые переполняют память.Поведение вашей программы, даже если оно правильное, не будет предсказуемым, пока они не будут исправлены.

Первый - char adjust_grades[1];, длина которого должна быть не менее 2, чтобы содержать 1 символ и терминатор NULL.

Второй - char temp_name_input[3];, который опять-таки не имеет места для терминатора NULL.

Далее - strlen(temp_name_input), который вызывается (дважды) до того, как temp_name_input является действительнымСтрока, поэтому результат является поддельным.Внимательно проверьте, что делает strncpy - не генерирует завершенную строку, если ваша исходная строка содержит более 3 символов, что верно для вашего случая.

Далее - char temp_student_name[3];,что опять-таки не достаточно долго.

На данный момент в вашей памяти все в порядке, и все ставки отменены.Вероятно, есть и другие проблемы, но начните с них, и вы будете на пути к чему-то более близкому.

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