【问题标题】:format '%s' expects argument of type '*char' but argument 2 has type 'int'格式“%s”需要“*char”类型的参数,但参数 2 的类型为“int”
【发布时间】:2018-10-24 11:25:30
【问题描述】:

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

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

【问题讨论】:

  • 你知道错误是在哪一行抛出的吗?如果您从scanf 中删除&amp; 会发生什么情况?
  • 一个 char 是单个字符。一个字母,数字左右。您有 20 个字符的空间用于 20 名学生的姓名。
  • 一个名字由多个字符和一个分数组成一个单数struct student。然后制作一个学生数组s
  • 第 19 和 21 行。
  • @scylla0120 - 要解决特定评论,您可以输入“@”,后跟用户名字。例如:@B. Cratty 在评论框中,它会标记您已回复的用户。

标签: c arrays string structure


【解决方案1】:

有几个问题:

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 教科书中。

【讨论】:

    【解决方案2】:

    您的代码有很多问题。 1)学生应该是数组(或动态分配内存)。 2) 字符串的 scanf 需要做为

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

    或者

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

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

    【讨论】:

      【解决方案3】:
      char name[20];
      

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

      要定义一个字符串数组,你需要一个char的二维数组,比如

      char name[NUMBER_OF_STRINGS][MAX_STRING_LENGTH+1];
      

      你把它读作

      scanf( “%s”, student.name[i] ); // no & operator here
      

      在大多数情况下,数组表达式“衰减”为指针表达式,因此这里不需要&amp; 运算符。

      或者,您可以声明一个指向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]

      【讨论】:

        【解决方案4】:

        学生姓名是char的单数数组,需要是字符数组的数组。

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

        我任意假设每个名称 40 个字符就足够了。

        名称的scanf需要更改为:

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

        收件人:

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

        【讨论】:

          【解决方案5】:

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

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

          您已经定义了一个名为Student 的新数据类型。 Student 类型的每个对象都有一个名为name 的字符串和一个类似于分数的int

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

          Student student1, student2;
          

          或者,您可以创建一个Students 数组: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'

          【讨论】:

          • 关于你的最后一句话:如果出现newline 字符,fgets保留它,但它不会追加 newline 否则为字符。 ASCII NUL 字节是 fgets 唯一会附加到它读取的字符串末尾的内容。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-03
          • 2021-01-26
          • 2013-05-10
          相关资源
          最近更新 更多