[英]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.