When I try to compile my program I get the warning message in the title and when I run it after scanning the names and scores it just stops. I encountered this problem a lot of times while practicing working with strings, but I haven't been able to find a solution.
#include <stdio.h>
struct students {
char name[20];
int score[20];
} student;
int main() {
int i, n;
printf("Number of students:\n");
scanf("%d", &n);
for(i=0; i<n; i++) {
printf("Name of the student:\n");
scanf("%s", &student.name[i]);
printf("Score of the student:\n");
scanf("%d", &student.score[i]);
}
for(i=0;i<n;i++) {
if(student.score[i] >= 15) {
printf("%s passed the exam\n", student.name[i]); }
else {
printf("%s failed the exam\n", student.name[i]);
}
}
return 0;
}
答案 0 :(得分:5)
有几个问题:
printf("%s passed the exam\n", student.name[i]);
student.name[i]
是char
,但是%s
格式说明符希望指向char
的指针。
但是实际的问题是,您声明的学生不是您所需要的。按照以下结构声明,一名学生的姓名最长为19个字符,并且得分为20。
struct students {
char name[20];
int score[20];
} student;
但是您需要20个(或更多?)学生,每个学生的得分都为:
struct student {
char name[50]; // name up to 49 characters
int score; // score
} student;
struct student students[20]; // array of 20 students
我将代码的实现留给读者作为练习。
您需要熟悉以下概念:
scanf
和printf
的基础所有这些主题都包含在您的C教科书中。
答案 1 :(得分:0)
您的代码有很多问题。 1)学生应该是数组(或动态分配的内存)。 2)字符串的scanf必须按照
scanf("%s", student[i].name)
或
scanf("%s", &student[i].name[0])
3)如果字符串长度超过20个字节(包括nul字符),仍然会出现问题。
答案 2 :(得分:0)
char name[20];
为单个 20个字符的字符串留出空间,因此students.name[i]
指单个字符(在int
中被提升为键入scanf
的字符致电)。
要定义 strings 的数组,您需要一个char
的二维数组,例如
char name[NUMBER_OF_STRINGS][MAX_STRING_LENGTH+1];
您读为
scanf( “%s”, student.name[i] ); // no & operator here
在大多数情况下,数组表达式会“衰减”为指针表达式,因此您在这里不需要&
运算符。
或者,您可以声明指向char
的指针的数组,例如
char *name[NUMBER_OF_STRINGS];
,然后在读取每个字符串时为其分配内存:
char buffer[MAX_STRING_LENGTH+1];
...
scanf( “%s”, buffer );
student.name[i] = malloc( strlen( buffer ) + 1 );
if ( student.name[i] )
strcpy( student.name[i], buffer );
完成后,您只需要记住free
个student.name[i]
。
答案 3 :(得分:0)
学生姓名是char的单数数组,必须是字符数组的数组。
struct students {
char name[20][40];
int score[20];
} student;
我任意假设每个名称40个字符就足够了。
名称的scanf需要更改为:
scanf("%s", &student.name[i]);
收件人:
scanf("%s", student.name[i]);
答案 4 :(得分:0)
scanf("%s", &student.name[i]);
您要从声明的字符串中寻址单个char
。我假设您会为每个学生想要一个单独的对象。为此,我的建议是像这样定义您的struct
:
typedef struct students {
char name[20];
int score;
}Student;
您已经定义了一个名为Student
的新数据类型。类型Student
的每个对象都有一个名为name
的字符串和一个类似于得分的int
。
创建此模型后,可以将其视为另一种变量类型,例如以下内容完全有效:
Student student1, student2;
或者,您可以创建一个Student
s数组:Student group[20]
,然后用一个循环填充数据:
for(int i = 0; i < n; i++){
puts("Name of the student: ");
fgets(group[i].name, 20, stdin);
puts("Score of the student: ");
scanf("%d", &group[i].score);
}
交易是每次迭代都引用学生数组中的单个对象。
另外,强烈建议使用fgets()
或至少使用gets_s()
来输入字符串。 scanf()
有多个问题,其中一些问题是,如果遇到空格,制表符或换行符,它将停止输入,最重要的是,它不检查数组范围。考虑使用更安全的变体,只需记住fgets()
在终止null之前附加一个'\n'
。