C结构声明问题

时间:2016-11-29 00:53:37

标签: c

我正在为我的编程基础类(C编程)编写以下程序。我的IDE给了我一个编译错误,用于声明“学生”#39;在读取用户输入的行中引用。它还给我一个关于letter_grade函数中嵌套函数的ISO C标准的错误。非常感谢任何帮助。

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

#define MAX 20

char letter_grade(float a, float b, float c);

int main(void)
{
char temp_name[MAX];
int count=0, last, temp;

struct student {
   char f_name[MAX];
   char l_name[MAX];
   float test1;
   float test2;
   float test3;
  };

printf("Please enter the student's last name (Enter ZZZ to exit): ");
   gets(temp_name);

while (strncmp(temp_name, "ZZZ\0", 4))
{
   strncpy(student[count].l_name, temp_name, MAX+1);
   printf("Please enter the students first name: ");
     scanf("%s", &student[count].f_name);
   getchar();
   printf("Enter the first test score: ");
     scanf("%f", &student[count].test1);
   printf("Enter the second test score: ");
     scanf("%f", &student[count].test2);
   printf("Enter the third test score: ");
     scanf("%f", &student[count].test3);
   printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
     gets(temp_name);
   count++;
}

last = count;

temp = last + 1;

printf("\t\t\tStudent Grade Report");

for (last;last>=0;last--){
    printf("%s, ", student[last].l_name);
    printf("%s ", student[last].f_name);
    printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));




//    printf("Test Grade: %c\n", letter_grade(85,88,82));


return 0;
}

char letter_grade(float *a, float *b, float *c)
{
float sum = *a+*b+*c;

if (sum >= 270.0f)
   return 'A';
if (sum>= 240.0f && sum <270.0f)
   return 'B';
if (sum>= 210.0f && sum <240.0f)
   return 'C';
if (sum>= 180.0f && sum <210.0f)
   return 'D';
if (sum < 180.0f)
   return 'F';
}

2 个答案:

答案 0 :(得分:2)

你没有声明一个名为student的数组或指针。该名称未被声明。因此,您在这里引用名称的代码就像这句话

strncpy(student[count].l_name, temp_name, MAX+1);
        ^^^^^^^

无效。

什么是“学生”?它在哪里宣布?

您只声明了类型struct student,但它与名为student的对象不同。

也在这个循环中

for (last;last>=0;last--){
    printf("%s, ", student[last].l_name);
    printf("%s ", student[last].f_name);
    printf("\t\t Grade: %c\n\n ", letter_grade(student[last].test1, student[last].test2, student[last].test2));

没有闭幕式。

答案 1 :(得分:1)

应用所有评论并更正已发布代码中的其他问题有很多结果:

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

#define MAX_NAME_LEN (20)
#define MAX_STUDENTS (100)

// define the student struc
struct student 
{
   char f_name[ MAX_NAME_LEN ];
   char l_name[ MAX_NAME_LEN ];
   float test1;
   float test2;
   float test3;
};

char letter_grade(float a, float b, float c);

int main(void)
{
    // define an array of 100 instances of the student struct
    struct student students[ MAX_STUDENTS ];

    printf("Please enter the student's last name (Enter ZZZ to exit): ");

    int count=0;      
    while( count < MAX_STUDENTS && scanf( " %19s", students[count].l_name)  && strcmp( students[count].l_name, "ZZZ" ) )
    {
         printf("Please enter the students first name: ");
         scanf(" %19s", students[count].f_name);

         printf("Enter the first test score: ");
         scanf("%f", &students[count].test1);

         printf("Enter the second test score: ");
         scanf("%f", &students[count].test2);

         printf("Enter the third test score: ");
         scanf("%f", &students[count].test3);

        count++;

        printf("\nPlease enter the student's last name (Enter ZZZ to exit): ");
    } // end while

    printf("\t\t\tStudent Grade Report");

    for ( ; count>=0; count--)
    {
        printf("%s, ", students[count].l_name);
        printf("%s ", students[count].f_name);
        printf("\t\t Grade: %c\n\n ", 
                letter_grade(   students[count].test1, 
                                students[count].test2, 
                                students[count].test2));
    }  // end for
} // end function: main


char letter_grade(float a, float b, float c)
{
    float sum = a+b+c;
    char grade;

    if( sum >= 270.f)      grade = 'A';
    else if (sum>= 240.0f) grade = 'B';
    else if (sum>= 210.0f) grade = 'C';
    else if (sum>= 180.0f) grade = 'D';
    else                   grade = 'F';

    return grade;
} // end function: letter_grade

您可以将发布的代码与上述答案进行比较,以找出发布代码中存在问题的位置。

不要#include头文件不使用这些内容。

函数的传递值不会成为被调用函数的参数列表中的指针。

在任何if then else序列中,无需重新测试先前消除的值

发布的代码将一个函数嵌套在另一个函数中,这不是有效的C代码,尽管可以使用gcc编译器扩展。

如果返回的值为0,则return不需要main()语句。

在任何非void函数中,代码中的所有路径必须导致return value;语句。

发布的代码未能声明struct student结构的任何实例。当然,并没有声明这些结构实例的数组,正如处理多个学生时所需要的那样。

如果任何名字或姓氏大于或等于20个字符,则发布的代码(和此答案)将失败。

此答案不会检查对scanf()的调用失败,但为了确保可靠性,必须对每个调用进行检查。类似于:

if( 1 != scanf( " %19s", students[count].l_name) )
{
    perror( "scanf failed" );
    exit( EXIT_FAILURE ); // `exit()` and `EXIT_FAILURE` found in stdlib.h
}

// implied else, scanf successful

为了清晰起见,while()函数中的main()语句非常“忙碌”,可以提取对strcmp()的调用并将其置于以下语句中,类似于:

while(...)
{
    if( !strcmp( students[count].l_name, "ZZZ" ) {
    {
         break;
    }
    ...

通常,永远不要相信用户的输入。这就是为什么需要检查每次调用scanf()的返回值(不是参数值)。

作为简化,而不是使用scanf()格式说明符对%s的调用中的MAX LENGTH修饰符进行硬编码,可以使用以下更改:

#define MAX_NAME_LEN (19)
...
struct student 
{
   char f_name[ MAX_NAME_LEN+1 ];
   char l_name[ MAX_NAME_LEN+1 ];
   float test1;
   float test2;
   float test3;
};
....
    && scanf(" %" MAX_NAME_LEN "s", students[count].l_name) &&
....
    scanf(" %" NAX_NAME_LEN "s", students[count].f_name);