我在MS-DOS上使用C,特别是Turbo C,我遇到了一些奇怪的问题,我的数据正在这里阅读。我有一个名为writeBitmap的函数,它实质上是一个带有路径,x和y大小的结构,然后是一个sprite表的偏移量,以及一个用这个定义每个图像的数组。
我遇到的问题是,当我重申从文件中获取的缓存图像数据时,如果以FF开头,则数组的输出总是被读取,好像它是一个整数。我的意思是,如果我的数组中有一个FF,当我使用if语句进行测试以查看它是否在那里它就像读取包含FF的整数,然后连接下一个字符。这意味着我无法检测到FF(顺便说一下,它是一个透明字节),因为无论何时出现,它都会读取它,然后同时读取下一个字节,即使是在转换为char时也是如此。
这是我的代码,我省略了一些东西,但最重要的是我有这些信息:
#include <dos.h>
#include <stdio.h>
/* define structs */
struct imageFile {
char path[16];
unsigned short size_x;
unsigned short size_y;
char offset;
};
/*define globals */
struct imageFile imgMap[1] =
{
{"./OUTP.DAT", 24, 24, 8}
};
这些是对函数很重要的变量,这是写的函数:
void writeBitmap(unsigned x, unsigned y, unsigned id){
int i, j, k;
int imgSize = (imgMap[id].size_x * imgMap[id].size_y); /*get size, init cache, and open file to offset*/
char *imgCache = (char *)malloc(imgSize);
FILE *fimg;
if(x + imgMap[id].size_x > 321 || y + imgMap[id].size_y > 201){
return;
}
fimg = fopen(imgMap[id].path, "rb");
fseek(fimg, (imgMap[id].offset * imgSize), SEEK_SET);
fread(imgCache, 1, imgSize, fimg);
fclose(fimg);
k = 0;
for(i = 0; i < imgMap[id].size_y; i++){
for(j = 0; j < imgMap[id].size_x; j++){
if((char)imgCache[k] != 0xFFFF){
/*setPixel(x + j, y + i, (char)imgCache[k]);*/
printf("%x ", imgCache[k]);
}/*else printf("TRANS: %x\n", imgCache[k]);*/
k++;
}
printf("\n");
}
}
setPixel指的是已知工作的另一个函数。它只计算图形模式0x13的段和偏移量,然后写入存储器。
所以,我目前在一些调试状态下设置了这个代码。我有它打印的东西,如果它不是0xFFFF,这消除了读取整数的任何东西。如果试图消除任何0xFF,它就不会消除它。
正如您所看到的,非0xFF的所有内容都被打印为1字节字符,但如果有一个0xFF,则会将其读取为整数以及下一个数据字节。
我不知道这是怎么发生的。我有一种感觉,它可能是我动态分配的数组,但它的类型为char,并且它不应该读取每个数组成员一次多于一个字节的数据。
答案 0 :(得分:2)
/* 1 */
{
"23613" : {
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
}
}
}
/* 2 */
{
"23658" : {
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
}
}
}
格式说明符需要%x
。 printf()包括其int
参数的默认参数提升。因此,除非您明确告诉它输入应该被视为char,否则它不会被激活。 int
在您的系统上是16位,因此打印了2个字节。
问题的根源是int
完全不适合用于除角色之外的任何事情。它具有实现定义的签名 - 在Turbo C上它与signed char相同。因此,当您在其中存储大于0x7F的值时,您将调用实现定义的转换为char
,最终得到负值。
解决方案是使用signed char
中的uint8_t
代替。由于您没有使用专业标准C工具链,而是使用侏罗纪时期的非标准工具链,因此您必须使用stdint.h
。
当您使用typedef unsigned char uint8_t
/ uint8_t
时,在printf转换为unsigned char
时不会有任何负号保留,您将获得预期产出。