简体   繁体   English

C结构声明问题

[英]C Structure Declaration Issue

I am writing the following program for my Programming Fundamentals Class (C Programming). 我正在为我的编程基础课(C编程)编写以下程序。 My IDE is giving me a compile error for the declaration of 'student' as referenced in the lines where user input is read. 我的IDE给了我一个在读取用户输入的行中引用的“学生”声明的编译错误。 It is also giving me an error on ISO C standards for nested functions in the letter_grade function. 它还给我提供了关于letter_grade函数中嵌套函数的ISO C标准错误。 Any help would greatly be appreciated. 任何帮助将不胜感激。

#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';
}

You nowhere declared an array or a pointer with name student . 您无处声明一个名称为student的数组或指针。 The name was not declared. 名称未声明。 Thus the code where you are refering the name like this statement 因此,您在其中引用此语句名称的代码

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

is invalid. 是无效的。

What is "student"? 什么是“学生”? Where is it declared? 声明在哪里?

You only declared type struct student but it is not the same as an object with name student . 您仅声明了类型struct student但它与名称为student的对象不同。

Also in this loop 同样在这个循环中

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));

there is absent the closing brace. 没有左括号。

Applying all the comments and correcting other problems in the posted code there were many results in: 将所有的意见和纠正其他问题在发布代码有许多的结果:

#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

You can compare the posted code to the above answer to spot where there were problems in the posted code. 您可以将发布的代码与上面的答案进行比较,以找出发布的代码中存在问题的地方。

Do not #include header files those contents are not used. 不要#include头文件,不要使用那些内容。

A passed value to a function does not become a pointer in the parameter list of the called function. 传递给函数的值不会成为被调用函数的参数列表中的指针。

In any if then else sequence, there is no need to re-test for previously eliminated values 在任何if then else ,都无需重新测试先前消除的值

The posted code nested one function inside another, That is not valid C code, although can be allowed with the gcc compiler extension. 发布的代码将一个函数嵌套在另一个函数中,虽然gcc编译器扩展可以允许使用,但这不是有效的C代码。

There is no need for a return statement from main() if the returned value is 0. 如果返回值为0,则不需要main()return语句。

On any non void function, ALL paths through the code must lead to a return value; 在任何非void函数上,通过代码的所有路径都必须导致return value; statement. 声明。

The posted code failed to declare any instance of the struct student structure. 发布的代码无法声明struct student结构的任何实例。 And certainly did not declare an array of those struct instances, as is needed when multiple students being processed. 当然也没有声明这些结构实例的数组,这是在处理多个学生时所需的。

The posted code (and this answer) will fail if any first or last name is greater than or equal to 20 characters. 如果任何姓氏或名字大于或等于20个字符,则发布的代码(和此答案)将失败。

This answer does not check for failures of the call to scanf() but for reliability, such checking for each must be performed. 此答案不是检查对scanf()的调用是否失败,而是为了确保可靠性,因此必须对每个检查都进行检查。 Similar to: 如同:

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

The while() statement in the main() function is very 'busy' for clarity, the call to strcmp() could be extracted and placed in a following statement similar to: 为了清楚起见, main()函数中的while()语句非常“忙”,可以提取对strcmp()的调用,并将其放在类似于以下的语句中:

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

In general, never trust the input from a user. 通常,永远不要信任用户的输入。 That is why the returned value (not the parameter value) from each call to scanf() needs to be checked. 这就是为什么需要检查每次对scanf()调用返回的值(而不是参数值)的原因。

As a simplification, rather than hardcoding the MAX LENGTH modifier in the calls to scanf() with a %s format specifier, can use the following changes: 为简化起见,可以使用以下更改,而不是在使用%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