我遇到一个问题:
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);
非常感谢您
答案 0 :(得分:2)
使用"%hhu"
代替"%d"
作为格式说明符。
答案 1 :(得分:2)
我认为int和uint8_t可以互换。
它们不是-int
(有符号或无符号)必须至少 16位宽(可以更宽,但不能更窄) 1 。顾名思义,uint8_t
是8位宽。
您需要使用格式说明符%hhu
来将数字值读入uint8_t
或unsigned char
对象中。
int
必须能够表示至少范围[-32767..32767]
中的所有值。至少需要16位。某些体系结构(我从未使用过)具有“填充位”,这些填充位有助于字长,但并不用于存储值。因此,例如,您可能有一台具有18位字的9位计算机,但是该系统上的实现仍可以选择仅使用16位来表示一个“ int”值-根本就不使用其中的两个位。
答案 2 :(得分:1)
要使用unsigned char
将整数读入(f)scanf
,则需要"%hhu"
。
答案 3 :(得分:1)
打印时,您可以避免使用%d
作为格式说明符,因为uint8_t
被传递给可变参数函数时被提示为int
像printf
。但是,对于指针来说并没有这种提升,这是scanf
对于大多数格式说明符所期望的。
您已经看到%d
的{{1}}的{{1}}格式说明符。在大多数系统上,您可能会遇到scanf
是4个字节。因此,当int *
取消引用您为int
提供的指针以写入值时,它将写入4个字节。如果您传入scanf
,则会中断此操作,因为此类型仅占用1个字节。通过使用%d
,uint8_t *
会认为您正在传递%d
的地址并写入4个字节,这是给定变量末尾3个字节。这样做会调用undefined behavior。
要解决此问题,请将格式说明符更改为scanf
,它需要int
。