【问题标题】:Change values on second level of multidimensional array while looping循环时更改第二级多维数组的值
【发布时间】:2019-11-05 07:57:11
【问题描述】:

我有一个硬件作业要完成。我已经完成了大部分工作,但我被困在一个地方。我在 C 中有一个二维字符串循环,代表学生和他们的成绩。

我的目标是让用户显示成绩,然后能够更新它们。我构建了数组以在两个空格字符后显示学生的姓名和最后的成绩。我设法达到了能够在硬编码数组中找到学生的地步。我也达到了可以隔离最后一个数组值(等级)并显示它的地步。我的问题是当我尝试将该值更新为新值时。我现在拥有代码的方式在替换成绩时会覆盖整个值以及学生姓名。

编辑: 我想更新,我相信当前的输出只是用更新的成绩覆盖了学生的数组值,但实际上它只是用更新的成绩值更新数组中的第一个值。

我尝试使用 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

【问题讨论】:

  • char adjust_grades[1]; 对于字母字符串空字符来说太小了。为什么这么小?
  • @chux adjust_grades 只是表示用户想要调整成绩。我并不是说我这样做的方式是对还是错,而是在我正在制作的程序的上下文中有效。这不是我遇到问题的地方。
  • 仍然太小 - 只够"",而不是"y"。在修复之前,其余代码无关紧要。
  • 不要写int i = NULL;——使用int i = 0;。仅在引用空指针时使用 NULL。在一些(很多?)系统上,NULL 被定义为((void *)0) 或类似的位置,并且分配一个指向整数的指针会引发编译器警告。
  • 正如已经指出的那样,您不能可靠地使用char adjust_grades[1]; 来读取字符串(%s)。它可能看起来有效。这是一个(不)幸运的巧合。您将强制 scanf() 在数组边界之外写入,这是危险的(未定义的行为)。它似乎有效;它不能被依赖。

标签: c string multidimensional-array


【解决方案1】:

您有几个缓冲区溢出,这些缓冲区溢出内存。你的程序的行为,即使是正确的,在它们被修复之前是不可预测的。

第一个是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];,还是不够长。

此时,您的记忆力已经完全恢复,因此所有的赌注都没有了。可能还有更多问题,但从这些开始,您将顺利完成任务。

【讨论】:

  • 感谢您的所有帮助。我查看了您提到的问题。我能够按预期运行该程序。再次感谢您的帮助!
猜你喜欢
  • 2020-10-08
  • 2012-11-08
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多