我正在为我的编程基础类(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';
}
答案 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);