警告:格式为“%d”,期望参数类型为“ int *”,但参数3的类型为“ uint8_t * {aka unsigned char *}

时间:2019-09-30 20:16:25

标签: c segmentation-fault

我遇到一个问题:

warning: format ‘%d’ expects argument of type ‘int *’, but argument 3 has type ‘uint8_t * {aka unsigned char *}

并且我不确定为什么会这样,因为我认为int和uint8_t是可互换的。

这是我的代码:

uint8_t** fileRead(char* file, int* pointer) {
    FILE* file = fopen(file, "r");
    int count = 0;
    pointer = &count;
    fscanf(file, "%d", &count); //this retrieves a single integer
    uint8_t** result = (uint8_t**) malloc(*pointer * sizeof(uint8_t*));
    while (file != NULL) {
        for (uint8_t i = 0; i < *pointer; i++) {
            uint8_t* a = (uint8_t*) malloc(sizeof(uint8_t));
            uint8_t* b = (uint8_t*) malloc(sizeof(uint8_t));
            uint8_t* c = (uint8_t*) malloc(sizeof(uint8_t));
            fscanf(file, "%d", a);
            fscanf(file, "%d", b);
            fscanf(file, "%d", c);
            if (a == NULL || b == NULL || c == NULL) {
                uint8_t* npointer = NULL;
                fclose(file);
                free(result);
                return NULL;
            } else {
                result[i][0] = *a;
                result[i][1] = *b;
                result[i][2] = *c;
                free(a);
                free(b);
                free(c);
           }
        }
    }
    return result; 
}

并且错误发生在以下几行:

fscanf(file, "%d", a);
fscanf(file, "%d", b);
fscanf(file, "%d", c);

非常感谢您

4 个答案:

答案 0 :(得分:2)

使用"%hhu"代替"%d"作为格式说明符。

答案 1 :(得分:2)

  

我认为int和uint8_t可以互换。

它们不是-int(有符号或无符号)必须至少 16位宽(可以更宽,但不能更窄) 1 。顾名思义,uint8_t是8位宽。

您需要使用格式说明符%hhu来将数字值读入uint8_tunsigned char对象中。


  1. 严格来说,int必须能够表示至少范围[-32767..32767]中的所有值。至少需要16位。某些体系结构(我从未使用过)具有“填充位”,这些填充位有助于字长,但并不用于存储值。因此,例如,您可能有一台具有18位字的9位计算机,但是该系统上的实现仍可以选择仅使用16位来表示一个“ int”值-根本就不使用其中的两个位。

答案 2 :(得分:1)

要使用unsigned char将整数读入(f)scanf,则需要"%hhu"

答案 3 :(得分:1)

打印时,您可以避免使用%d作为格式说明符,因为uint8_t被传递给可变参数函数时被提示intprintf。但是,对于指针来说并没有这种提升,这是scanf对于大多数格式说明符所期望的。

您已经看到%d的{​​{1}}的{​​{1}}格式说明符。在大多数系统上,您可能会遇到scanf是4个字节。因此,当int *取消引用您为int提供的指针以写入值时,它将写入4个字节。如果您传入scanf,则会中断此操作,因为此类型仅占用1个字节。通过使用%duint8_t *会认为您正在传递%d的地址并写入4个字节,这是给定变量末尾3个字节。这样做会调用undefined behavior

要解决此问题,请将格式说明符更改为scanf,它需要int