格式“%s”需要类型为“*char”的参数,但参数 2 的类型为 'int'

format '%s' expects argument of type '*char' but argument 2 has type 'int'

当我尝试编译我的程序时,我在标题中收到警告消息,当我 运行 它在扫描名称和分数后它就停止了。我在练习使用字符串时遇到过很多次这个问题,但我一直没能找到解决办法。

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

有几个问题:

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

我把代码的实现留给 reader 作为练习。 您需要熟悉以下概念:

  • 数组
  • 结构
  • 字符串
  • scanfprintf
  • 的基础知识

所有这些主题都包含在您的 C 课本中。

你的代码有不少问题。 1)学生应该是数组(或动态内存分配)。 2) 字符串的 scanf 需要按

完成

scanf("%s", student[i].name)

scanf("%s", &student[i].name[0])

3) 如果字符串长度超过 20 个字节(包括 nul 字符),您仍然会遇到问题。

char name[20];

单个 20 个字符的字符串留出 space,因此 students.name[i] 指的是单个字符(被提升为类型 intscanf 调用中)。

要定义一个 字符串数组 ,你需要一个 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] 当你完成时。

学生姓名为单数char数组,需为字符数组数组

struct students {
    char name[20][40];
    int score[20];
} student;

我武断地假设每个名字 40 个字符就足够了。

名称的 scanf 需要更改为:

scanf("%s", &student.name[i]);

收件人:

scanf("%s", student.name[i]);

scanf("%s", &student.name[i]); 您正在从声明的字符串中寻址单个 char。我假设您希望每个学生都有一个单独的对象。为此,我的建议是像这样定义 struct

typedef struct students {
    char name[20];
    int score;
}Student;

这样您就定义了一个名为 Student 的新数据类型。 Student 类型的每个对象都有一个名为 name 的字符串和一个类似于乐谱的 int

创建此模型后,您可以将其视为另一种变量类型,例如以下是完全有效的:

Student student1, student2;

或者,您可以创建一个 Student 数组: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() 有多个问题,其中一些问题是它在遇到 space、制表符或换行符时停止输入,最重要的是它不检查数组边界。考虑使用更安全的变体,请记住 fgets() 在终止 null 之前附加一个 '\n'