【问题标题】:warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]警告:格式“%s”需要“char *”类型的参数,但参数 2 的类型为“char (*)[30]”[-Wformat=]
【发布时间】:2019-05-06 21:58:35
【问题描述】:

我正在与学生一起创建一个数据库,我创建了一个struct Students

struct Students {
    //struct specific for students
    char first_name[30];
    char last_name[30];
    int ssn;
};

void add_student() {
    //function to add students
    int i, n;
    struct Students *student;
    printf("How many students are you adding");
    scanf("%d", &n);

    student = (struct Students *)malloc(n * sizeof(struct Students *)); //allocate the memory for n students

    for (i = 0; i < n; i++) {
        printf("Enter first, last and ssn respectively");
        scanf(" %s ", &(student+i)->first_name); //adds first name to student i
        scanf(" %s ", &(student+i)->last_name);// adds last name to student i
        scanf(" %d ", &(student+i)->ssn); //adds ssn to student i
    }

    for (i = 0; i < n; i++) {
        //print each of the students being added
        printf("First name: %s\n ", (student+i)->first_name);
        printf("Last name: %s\n ", (student+i)->last_name);
        printf("ssn: %d\n ", (student+i)->ssn);
    }
    free(student); //free the memory used 
}

预期:我正在尝试为数据库添加学生并打印它们 以确保它们实际上被写入结构。

实际:

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
    scanf(" %s ", &(student+i)->first_name);

【问题讨论】:

  • &amp; 不需要 first_namelast_name
  • 是否需要免费(学生),因为当我运行程序时 *** `./Project' 中的错误:free():下一个大小无效(快速):0x0000000002133830 ***
  • 该错误表明内存已损坏。您需要发布minimal reproducible example,包括您提供给程序的输入。
  • 顺便说一句,(student+i)-&gt;student[i]. 相同,后者更容易阅读,imo。
  • 并且不要强制转换 malloc。在 C 中它是不必要的,并且可以隐藏其他问题。

标签: c struct


【解决方案1】:

只需将数组作为参数传递,它将衰减为指向其第一个元素的指针:

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

您正在传递数组的地址,该地址与第一个元素的地址具有相同的值但类型不同。编译器将这种类型不匹配检测为发出警告(这是非常好事!)

以下是代码中其他问题的列表:

  • 您应该测试scanf() 的返回值以检测无效或丢失的输入。
  • 还对使用scanf() 输入的值添加有效性测试。
  • Students 数组分配的内存不正确:您分配n 时间是指针的大小,您应该分配n 时间Student struct 本身的大小。
  • 删除scanf() 格式字符串中的尾随空格。这些会导致无缘无故读取额外的输入。
  • 还要添加要存储到目标数组中的最大字符数:"%29s"
  • 测试scanf() 的返回值以检测丢失的输入。

这是一个更正的版本:

struct Students {
    //struct specific for students
    char first_name[30];
    char last_name[30];
    int ssn;
};

void add_student() {
    //function to add students
    int i, n;
    struct Students *student;

    printf("How many students are you adding");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("invalid input\n");
        return 1;
    }

    // Allocate the memory for n students
    student = malloc(n * sizeof(struct Students));

    for (i = 0; i < n; i++) {
        printf("Enter first, last and ssn respectively: ");
        if (scanf("%s", student[i].first_name) != 1
        ||  scanf("%s", student[i].last_name) != 1
        ||  scanf("%d", student[i].ssn) != 1) {
            printf("invalid input or missing input\n");
            n = i; // only `i` students have ben read
            break;
        }
    }

    for (i = 0; i < n; i++) {
        // print each of the students being added
        printf("First name: %s\n", student[i].first_name);
        printf("Last name: %s\n", student[i].last_name);
        printf("ssn: %d\n", student[i].ssn);
    }
    free(student); //free the memory used 
}

【讨论】:

  • @M.M:确实是一个更好的格式字符串,以及其他我一见钟情没有发现的问题:)
【解决方案2】:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 
has type ‘char (*)[30]’ [-Wformat=]

显示此警告是因为您在扫描(student+i)-&gt;first_name(student+i)-&gt;last_name 时使用了&amp;。扫描 string 时,您不需要在变量名前加上 &amp;。请注意,&amp; 需要在所有其他变量类型之前使用。

将此改为行:

scanf(" %s ", &(student+i)->first_name);
scanf(" %s ", &(student+i)->last_name);

scanf(" %s ", (student+i)->first_name);
scanf(" %s ", (student+i)->last_name);

警告会消失

【讨论】:

  • scanf格式字符串中不能有尾随空格
猜你喜欢
  • 1970-01-01
  • 2013-05-10
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
相关资源
最近更新 更多