繁体   English   中英

C结构声明问题

[英]C Structure Declaration Issue

我正在为我的编程基础课(C编程)编写以下程序。 我的IDE给了我一个在读取用户输入的行中引用的“学生”声明的编译错误。 它还给我提供了关于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';
}

您无处声明一个名称为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));

没有左括号。

将所有的意见和纠正其他问题在发布代码有许多的结果:

#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 ,都无需重新测试先前消除的值

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

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

在任何非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

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

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

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

为简化起见,可以使用以下更改,而不是在使用%s格式说明符对scanf()的调用中对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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM