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

时间:2018-10-24 11:25:31

标签: c arrays string structure

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

5 个答案:

答案 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
我将代码的实现留给读者作为练习。 您需要熟悉以下概念:

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

所有这些主题都包含在您的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 );

完成后,您只需要记住freestudent.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'