0

好的,所以如果修复了它,我它像样的做了一些建议,我得到了同样的错误(我正在使用 codebloks btw),它的错误只是在没有给出原因的情况下崩溃。我遇到了第二个错误。在输入年龄后的 getinfo 函数中,它打印获取性别的语句,然后打印获取其他人姓名的语句而不让我输入(它似乎只是跳过了那部分

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

void getinfo (char* nam[],int ag[], char gender[], int count){
 int y;
 for(y = 0; y < count; y++){
 nam[y] = malloc(30);
 printf ("What is the student's name?\t");
 scanf ("%s", &nam[y]);
 printf ("\nWhat is the students age?\t");
 scanf ("%d", &ag[y]);
 printf ("\nwhat is the students gender, M/F:\t");
 scanf ("%c", &gender[y]);
  }
 }

void findeldest (char* nam[],int ag[], char* gender[], int count){
 int largest = 0, y, eldest =0 ;
 for(y = 0; y < count; y++){
    if (ag[y] > eldest){
        largest = ag[y];
        eldest = y;
        }
    }
    printf ("The eldest student is:\t%s", nam[eldest]);
    printf ("\nGender:\t%c", gender[eldest]);
    printf ("\nWith an age of:\t%d", ag[eldest]);

}


int main (){
  int amount, y;
  printf("How many students are you admitting?\t");
  scanf ("%d", &amount);
  if (amount > 50){
  printf("Too many students!");
   }else{
   char *name[50];
   int age[50];
   char gender[50];
   getinfo(name, age, gender, amount);
   findeldest(name, age, gender, amount);
   system("pause");
  }
}
4

2 回答 2

3

提供的代码不可编译,因此我们无法正确诊断问题。请使用可编译的测试用例更新您的帖子,该测试用例仅包含重现您的问题所需的基本要素。

if (ag[y] > eldest){
    largest = ag[y];
    eldest = y;
    } /* <--- Note the inconsistent indentation.
       *      Do you want us to read your code and help you?
       *      If so, please fix your indentation.
       */

应该是对年龄进行比较,然后将索引分配给年龄变量?老大在哪家店?索引,还是年龄?任你选择,并使其保持一致。也许使用更具描述性的标识符可能是一个更好的主意,例如“eldest_index”和“eldest_age”。这将提供内部文档,“eldest_index”是最老的人的数组索引,“eldest_age”是最老的人的年龄。看起来最大的商店已经老化,也许您的代码应该看起来更像:

if (ag[y] > largest){
    largest = ag[y];
    eldest = y;
}

printf ("\nGender:\t%c", gender[eldest]);如果 eldest 存储年龄,而不是索引,那么这不会导致您的程序在什么时候崩溃eldest >= 50?我认为当你想出更好的标识符时,这个陈述会更有意义。此外,gender[eldest]is a char *, where%c告诉 printf 期望inta 具有字符值。


编辑:如果您在使用 scanf 之前阅读了此 scanf 手册,您就不会遇到第二个错误。事实上,在阅读它的文档之前使用 scanf你的错误;请停下。

如果你放在printf("The character entered for gender has an integer value of %d\n", (unsigned char) gender[y]);之后scanf ("%c", &gender[y]);,你会得到什么价值?'\n' 是有效的性别吗?

...所以您已经解决了当用户在整数读取和字符读取之间按下回车键时发生的问题。伟大的!如果不阅读手册,您将遇到第三个问题。假设用户按下“M”或“F”,然后按回车。这将导致 'M' 或 'F' 从 stdin 读取scanf ("%c", &gender[y]);,但 '\n' 将保留在 stdin 上。这样做有什么影响?当循环重复时,您告诉 scanf 读取但不包括下一个空白字符(这是 '%s' 所指示的),您最终会得到一个空白名称!哎呀!

假设您希望用户在输入性别之前和之后按Enterscanf ("%c", &gender[y]); ,我建议更改为:

int c;
for (c = getchar(); c >= 0 && c != '\n'; c = getchar());  /* Discard the remainder of the line,
                                                           * so that it doesn't interfere with
                                                           * the gender input.
                                                           */
gender[y] = c;
for (c = getchar(); c >= 0 && c != '\n'; c = getchar());  /* Discard the remainder of the line,
                                                           * so that it doesn't interfere with
                                                           * the next scanf call.
                                                           */

...并且不要忘记仔细阅读该 scanf 手册!

于 2013-03-09T04:35:49.180 回答
1

您没有发布 getinfo 函数的源代码,所以我们在这里能做的最好的就是猜测。我首先要看的是 getinfo,当它填充“nam”和“gender”参数时。您很可能会为这些使用堆栈本地字符串。一旦“getinfo”函数返回,这些字符串就不再存在。但是,指向堆栈上这些位置的指针仍然存在,并且每当 findeldest 尝试在 printf 中使用这些指针时,它都会从堆栈中打印出垃圾。

如果您提供您的“getinfo”实现,这将更容易。这是我的实现

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

void findeldest (char* nam[],int ag[], char* gender[], int count){
  int largest = 0, y, eldest =0 ;
  for(y = 0; y < count; y++){
    if (ag[y] > eldest){
      largest = ag[y];
      eldest = y;
    }
  }
  printf ("The eldest student is:\t%s", nam[eldest]);
  printf ("\nGender:\t%s", gender[eldest]);
  printf ("\nWith an age of:\t%d", ag[eldest]);

}

void getinfo(char* nam[],int ag[], char* gender[], int count)
{
    static const char * const MALE = "male";
    static const char * const FEMALE = "female";

    static const char * const BRIAN = "brian";
    static const char * const SUE = "sue";
    static const char * const DAVE = "dave";
    static const char * const APRIL ="april";



    for(int i = 0 ; i < count ; ++i)
    {
        ag[i] = i;

        switch(i%4)
        {
            case 0:
                nam[i] = BRIAN;
                break;
            case 1:
                nam[i] = SUE;
                break;
            case 2:
                nam[i] = DAVE;
                break;
            case 3:
                nam[i] = APRIL; 
                break;

        }

        switch(i%2)
        {
            case 0:
                gender[i] = MALE;
                break;
            case 1:
                gender[i] = FEMALE;
                break;
        }

    }
    return;
}

int main (){
  int amount, y;
  printf("How many students are you admitting?\t");
  scanf ("%d", &amount);
  if (amount > 50){
    printf("Too many students!");
  } else {
    char *name[50];
    int age[50];
    char *gender[50];
    getinfo(name, age, gender, amount);
    findeldest(name, age, gender, amount);
    system("pause");
  }
}

这对我来说可以。请注意对 findeldest 中第二个“printf”语句的更正。当您的意思是 %s (以空字符结尾的字符串)时,您使用的是 %c (单个字符)。

此外,您没有使用符合 C90 的代码。发布时,您应该指定正在使用的编译器以及编译所需的选项(如果有的话)。它似乎接近有效的 C99 代码。我收到一些关于在我的“getinfo”实现中滥用 const 的编译器警告。

于 2013-03-09T04:42:42.577 回答