fread / ftell显然在Windows下坏了,在Linux下工作正常 [英] fread/ftell apparently broken under Windows, works fine under Linux

查看:249
本文介绍了fread / ftell显然在Windows下坏了,在Linux下工作正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  @ 0这个问题,我正在阅读我的游戏的关卡文件, 
@ 12
200x200版本3
@ 16
973块
@ 989
@ 993
18个区域

但是在windows下,我得到以下结果:

  @ 0 
@ 212
200x200版本3
@ 216
973块
@ 1200
@ 1204
18个区域

呃?窗口ftell统计偏移量为200?读取文件显然会产生相同的数据,但fread使用(?)ftell的值来确定文件中可以读取的字节数。所以当然,我在阅读文件的最后遇到问题:

  @ 1425 
zone# 9 2x3 @ 66/9
@ 1425
区#10 2x3 @ 66/9
@ 1425
区#11 2x3 @ 66/9
@ 1425
区#12 2x3 @ 66/9
@ 1425
区#13 2x3 @ 66/9
@ 1425
区#14 2x3 @ 66/9
等等。

这是相应的代码(由于所有的调试打印, :

pre $ void $ fread_all void * ,大小,数量,流);
printf(@%ld\\\
,ftell(stream));


$ b bool map_load(struct Map * map,const char * file_name){
FILE * fp = fopen(file_name,r);
if(fp!= NULL){
fseek(fp,0,SEEK_SET);
printf(@%ld\\\
,ftell(fp));

// Header
int * header =(int *)calloc(sizeof(int),3);
fread_all(header,sizeof(int),3,fp);
printf(%dx%d version%d \ n,header [0],header [1],header [2]);

map-> pos_x = 0;
map-> pos_y = 0;
map-> map_x = 0;
map-> map_y = 0;
map-> size_x = header [0];
map-> size_y = header [1];
map_zones_remove(map);
free(header);
$ b //块
unsigned int * block_size =(unsigned int *)malloc(sizeof(unsigned int));
fread_all(block_size,sizeof(int),1,fp);
printf(%d blocks \\\
,* block_size);

unsigned char * block_data =(unsigned char *)calloc(sizeof(unsigned char),* block_size);
fread_all(block_data,sizeof(unsigned char),* block_size,fp);

unsigned char * tmp = map-> blocks;
map-> blocks = rle_decode(block_data,* block_size);
free(tmp);
free(block_size);
free(block_data);
$ b $ //区域
int * zone_count =(int *)malloc(sizeof(int));
fread_all(zone_count,sizeof(int),1,fp);
printf(%d zones\\\
,* zone_count);
$ b $ int * d =(int *)calloc(sizeof(int),6); (int i = 0,l = * zone_count; i <1; i ++){
fread_all(d,sizeof(int),6,fp)的

map_zone_create(map,d [0],d [1],d [2],d [3],d [4],d [5]);
printf(zone#%d%dx%d @%d /%d\\\
,i,d [2],d [3],d [0],d [1]);
}
map_platforms_create(map);

free(zone_count);
免费(d);
fclose(fp);
返回true;
}
返回false;
}

我真的不知道这里发生了什么。编译器是在Linux下的Visual Studio 10和GCC 4.4。

解决方案

以二进制模式打开文件b
$ b

  FILE * fp = fopen(file_name,rb);在文本模式下,可能有翻译正在进行以匹配例如与操作系统相关的编码。换行到C库。


So here's the problem, I'm reading a level file for my game, works fine under linux:

@0
@12
200x200 version 3
@16
973 blocks
@989
@993
18 zones

But under windows I get the following result:

@0
@212
200x200 version 3
@216
973 blocks
@1200
@1204
18 zones

Uh? The windows ftell stats with an offset of 200? Reading the file apparently yields the same data, but fread uses(?) the value of ftell to determine the how many bytes are left in the file that can be read. So of course I'm running into problems when reading at the end of the file:

@1425
zone#9 2x3 @ 66/9
@1425
zone#10 2x3 @ 66/9
@1425
zone#11 2x3 @ 66/9
@1425
zone#12 2x3 @ 66/9
@1425
zone#13 2x3 @ 66/9
@1425
zone#14 2x3 @ 66/9
etc.

This is the corresponding code(currently a bit ugly due to all the debug prints..):

void fread_all(void *ptr, size_t size, size_t count, FILE *stream) {
    fread(ptr, size, count, stream);
    printf("@%ld\n", ftell(stream));
}


bool map_load(struct Map *map, const char *file_name) {
    FILE *fp = fopen(file_name, "r");
    if (fp != NULL) {
        fseek(fp, 0, SEEK_SET);
        printf("@%ld\n", ftell(fp));

        // Header
        int *header = (int*)calloc(sizeof(int), 3);
        fread_all(header, sizeof(int), 3, fp);
        printf("%dx%d version %d\n", header[0], header[1], header[2]);

        map->pos_x = 0;
        map->pos_y = 0;
        map->map_x = 0;
        map->map_y = 0;
        map->size_x = header[0];
        map->size_y = header[1];
        map_zones_remove(map);        
        free(header);

        // Blocks
        unsigned int *block_size = (unsigned int*)malloc(sizeof(unsigned int));
        fread_all(block_size, sizeof(int), 1, fp);
        printf("%d blocks\n", *block_size);

        unsigned char *block_data = (unsigned char*)calloc(sizeof(unsigned char), *block_size);
        fread_all(block_data, sizeof(unsigned char), *block_size, fp);

        unsigned char *tmp = map->blocks;
        map->blocks = rle_decode(block_data, *block_size);
        free(tmp);
        free(block_size);
        free(block_data);

        // Zones
        int *zone_count = (int*)malloc(sizeof(int));
        fread_all(zone_count, sizeof(int), 1, fp);
        printf("%d zones\n", *zone_count);

        int *d = (int*)calloc(sizeof(int), 6);
        for(int i = 0, l = *zone_count; i < l; i++) {
            fread_all(d, sizeof(int), 6, fp);
            map_zone_create(map, d[0], d[1], d[2], d[3], d[4], d[5]);
            printf("zone#%d %dx%d @ %d/%d\n", i, d[2], d[3], d[0], d[1]);
        }
        map_platforms_create(map);

        free(zone_count);
        free(d);
        fclose(fp);
        return true;
    }
    return false;
}

I really have no clue what's going on here. Compilers are the Visual Studio 10 one and GCC 4.4 under Linux.

解决方案

Open your file in binary mode:

FILE *fp = fopen(file_name, "rb");

In text mode, there might be translations going on to match the operating system-dependent encoding of e.g. line feeds to the C library's.

这篇关于fread / ftell显然在Windows下坏了,在Linux下工作正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆