C Structure Declaration Issue

I am writing the following program for my Programming Fundamentals Class (C Programming). My IDE is giving me a compile error for the declaration of 'student' as referenced in the lines where user input is read. It is also giving me an error on ISO C standards for nested functions in the letter_grade function. 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';
}

Upvotes: 0

Views: 114

Answers (2)

user3629249
user3629249

Reputation: 16540

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.

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

The posted code nested one function inside another, That is not valid C code, although can be allowed with the gcc compiler extension.

There is no need for a return statement from main() if the returned value is 0.

On any non void function, ALL paths through the code must lead to a return value; statement.

The posted code failed to declare any instance of the struct student structure. 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.

This answer does not check for failures of the call to scanf() but for reliability, such checking for each must be performed. 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:

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.

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:

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

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310920

You nowhere declared an array or a pointer with name 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.

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.

Upvotes: 2

Related Questions