【问题标题】:C Format '%d' expects argument of type 'int *' but argument 2 has type 'unsigned int' [-Wformat=]C 格式“%d”需要“int *”类型的参数,但参数 2 的类型为“unsigned int”[-Wformat=]
【发布时间】:2015-10-15 20:28:43
【问题描述】:

我对这段代码有一些问题,我想编译它,但它没有编译,因为有问题。我告诉了那里的错误代码......

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 1000                                 
typedef struct{
    int film_id;
    char title[255];
    char description[1023];
    unsigned int release_year;
    char rental_duration;
    float rental_rate;
    unsigned char length;
    float replacement_cost;
    char rating[10];
    char last_update[30];
} RECORD_t, *RECORD;                                   

int main(){
    int i,R1;
    char R[1];
    RECORD rec = (RECORD)malloc(sizeof(RECORD_t)*MAX);  
    FILE *file = fopen("data.txt", "rb");               
    if (file == NULL) {                                 
        printf("Cannot open the file.\n");          
        exit(0);                                    
    }                                                   
    fread(rec, sizeof(RECORD_t)*MAX, 1, file);          
    fclose(file);                                       

printf("İd Numarası Giriniz : \n"); 
        scanf("%d",&R1);
        for (i=0; i<1000; i++){
            if (R1 == rec[i].film_id) {

            printf("TITLE: %s\n", rec[i].title); printf("Enter New TITLE : "); scanf("%s",rec[i].title);
            printf("DESCRIPTION: %s\n", rec[i].description); printf("Enter New Description : "); scanf("%s",rec[i].description);

// My problem is this line :-------------------
            printf("RELEASE YEAR: %d\n", rec[i].release_year); printf("Enter New RELEASE YEAR : "); scanf("%d",rec[i].release_year);
            printf("RENTAL DURATION: %d\n", rec[i].rental_duration); printf("Enter New RENTAL DURATION : "); scanf("%d",rec[i].rental_duration);
            printf("RENTAL RATE: %f\n", rec[i].rental_rate); printf("Enter New RENTAL RATE : "); scanf("%f",rec[i].rental_rate);
            printf("REPLACEMENT COST: %f\n", rec[i].replacement_cost); printf("Enter New REPLACEMENT COST : "); scanf("%f",rec[i].replacement_cost);
            printf("RATING: %s\n", rec[i].rating); printf("Enter New RATING : "); scanf("%s",rec[i].rating);
            printf("LAST UPDATE: %s\n", rec[i].last_update); printf("Enter New LAST UPDATE : "); scanf("%s",rec[i].last_update);

            }
        }

    }   


    file = fopen("data.txt", "wb");                  
    fwrite(rec, sizeof(RECORD_t)*MAX, 1, file);      
    fclose(file);                                    
    free(rec);                                       
    return 1;                                        
}

编译时只有 int 和 float 变量不起作用

warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘unsigned int’ [-Wformat=]
    printf("RELEASE YEAR: %d\n", rec[i].release_year); printf("Enter New RELEASE YEAR : "); scanf("%d",rec[i].release_year);
    ^

请帮帮我://

【问题讨论】:

  • 1) scanf("%s",rec[i].title); 不会阻止对 title 的阅读过多。最好使用scanf("%254s",rec[i].title); 2) scanf("%s",rec[i].title); 将无法读取带有空格的图块 3) 推荐memset(rec[i].title, 0, sizeof rec[i].title); 在将标题读入它之前擦洗随机数据字段 - 在调试时有用记录。
  • 将格式字符串中的%d更改为%u,以匹配无符号数。

标签: c


【解决方案1】:

scanf%d%f 格式说明符分别期望intfloat 的地址。另外release_yearunsigned int,所以应该使用%u 说明符,对于rental_duration,它是char,应该使用%hhd

所以这些:

scanf("%d",rec[i].release_year);
scanf("%d",rec[i].rental_duration);
scanf("%f",rec[i].rental_rate);
scanf("%f",rec[i].replacement_cost);

应改为:

scanf("%u",&rec[i].release_year);
scanf("%hhd",&rec[i].rental_duration);
scanf("%f",&rec[i].rental_rate);
scanf("%f",&rec[i].replacement_cost);

您没有看到%s 的问题,因为数组——当传递给函数时——衰减为指向数组第一个元素的指针。

编辑:

scanf 使用正确的大小说明符特别重要。如果您使用%d 而不是%hhd 作为charscanf 将尝试写入一个4 字节的位置(假设int 是32 位)而不是一个字节,这将导致到未定义的行为。

来自手册页:

   h      Indicates that the conversion will be one of diouxX or n and the
          next  pointer  is a pointer to a short int or unsigned short int
          (rather than int).

   hh     As for h, but the next pointer is a pointer to a signed char  or
          unsigned char.

   l      Indicates either that the conversion will be one of diouxX or  n
          and the next pointer is a pointer to a long int or unsigned long
          int (rather than int), or that the conversion will be one of efg
          and the next pointer is a pointer to double (rather than float).
          Specifying two l characters is equivalent to L.  If used with %c
          or  %s the corresponding parameter is considered as a pointer to
          a wide character or wide character string respectively.

   L      Indicates that the conversion will be either efg  and  the  next
          pointer  is  a  pointer to long double or the conversion will be
          dioux and the next pointer is a pointer to long long.

【讨论】:

  • @Olaf 谢谢。固定,再加上一个。
  • 嗯...如果char 未签名怎么办? IMO char 没有 signed/unsigned 真的应该只用于字符。
  • %hhu 可用于unsigned char。我同意,尽管鉴于其典型用法,使用 char 进行数字输入可能会让读者感到困惑。
  • 问题是,char 用于数字输入,您不知道使用哪个说明符。无论如何,使用比(unsigned) int 更小的类型是没有意义的。 OP 当然没有内存空间问题。
  • @Olaf 对于char,您必须使用%hhd%hhu,否则scanf 将尝试写入多个字节,从而导致未定义的行为。同样,shortunsigned short 分别需要 %hd%hu
【解决方案2】:

调用scanf()时需要传递变量的地址

scanf("%d", &rec[i].release_year);

【讨论】:

  • rental_durationrental_ratereplacement_cost 相同。
  • 他还必须使用unsigned 格式说明符。
【解决方案3】:

显然你的问题来自scanf("%d",rec[i].release_year);

scanf 需要一个指向变量的指针,以便能够将读取的值存储到其中。所以一定是:scanf("%d",&amp;(rec[i].release_year));

注意:不要将多个命令放在同一行。您的工具将您指向错误所在的行,而不是引发错误的函数。如果你把这条线分成 3 (printf+printf+scanf) 你会更快地看到问题出在哪里:)

【讨论】:

  • 他还必须使用unsigned 格式说明符。
  • 如果我没记错的话,它会导致警告,而不是错误,它会起作用(并不总是像预期的那样,但是……)。但是,是的,你是对的。
  • IIRC 格式字符串/可变参数错误总是报告为警告,无论给出什么类型组合。
  • 我的意思是用无符号整数格式(或反向)打印一个整数是可行的(有时会根据内容/类型产生奇怪的结果),但给出一个(无符号)整数而不是指向有效的内存区域会导致段错误。但最后一个段错误会更好,因为你必须纠正它:)
  • 它充其量是定义的实现。实际上,由于它是通过指针传递的,它实际上违反了严格的别名规则(没有转换,而是重新解释)。而且,不,它不一定是段错误,但正是 UB 准确地描述了将会发生的事情。 Segfault 是一个(不可靠的)操作系统功能,标准没有提到是有充分理由的。
猜你喜欢
  • 2014-02-03
  • 2021-06-22
  • 2012-10-04
  • 2015-02-27
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
相关资源
最近更新 更多