Linux下文件读取方式不同? C++

发布于 2024-09-25 02:40:57 字数 1459 浏览 6 评论 0原文

我是一个相当新的程序员,但我认为我的 google-fu 非常有能力,并且我花了几个小时进行搜索。

我有一个简单的 SDL 应用程序,它从二进制文件中读取(2 个字节作为幻数,然后每个“图块”5 个字节) 然后它显示缓冲区中的每个图块,字节决定 x、y、id、可通过性等。 所以这实际上只是关卡加载。

它可以在任何 Windows 计算机上正常运行(已测试 Windows Server 2008、7/64 和 7/32) 但是当我在 Linux 上编译它时,它会在随机位置显示随机图块。 我很想说它是从 RAM 中的错误部分读取的,但我实现了幻数,因此如果前 2 个字节耗尽,它会返回错误。

我很想自己解决这个问题,但它现在让我烦恼极了,除非我可以在移动中编程(我的笔记本电脑运行 Linux),否则我无法进一步取得进展。 我在 Linux 上使用 G++,在 Windows 上使用 mingw32g++。

bool loadlevel(int level_number)
{
    int length;
    std::string filename;
    filename = "Levels/level";
    filename += level_number+48;
    filename += ".lvl";
    std::ifstream level;
    level.open(filename.c_str(),std::ios::in|std::ios::binary);
    level.seekg(0,std::ios::end);
    length = level.tellg();
    level.seekg(0,std::ios::beg);
    char buffer[length];
    level.read(buffer,length);
    if (buffer[0] == 0x49 && buffer[1] == 0x14)
    {
        char tile_buffer[BYTES_PER_TILE];
        int buffer_place = 1;
        while(buffer_place < length)
        {
            for (int i = 1;i <= BYTES_PER_TILE;i++)
            {
                tile_buffer[i] = buffer[buffer_place+1];
                buffer_place++;
            }
            apply_surface(tile_buffer[1],tile_buffer[2],tiles,screen,&clip[tile_buffer[3]]);
        }
    }
    else
    {
        // File is invalid
        return false;
    }
    level.close();
    return true;
}

提前致谢!

I'm a fairly new programmer, but I consider my google-fu quite competent and I've spent several hours searching.

I've got a simple SDL application that reads from a binary file (2 bytes as a magic number, then 5 bytes per "tile")
it then displays each tile in the buffer, the bytes decide the x,y,id,passability and such.
So it's just level loading really.

It runs fine on any windows computer (tested windows server 2008, 7/64 and 7/32)
but when I compile it on linux, it displays random tiles in random positions.
I'd be tempted to say it's reading from the wrong portion in the RAM, but I implimented the magic number so it'd return an error if the first 2 bytes were out.

I'd love to figure this out myself but it's bugging me to hell now and I can't progress much further with it unless I can program on the move (my laptop runs linux).
I'm using G++ on linux, mingw32g++ on windows.

bool loadlevel(int level_number)
{
    int length;
    std::string filename;
    filename = "Levels/level";
    filename += level_number+48;
    filename += ".lvl";
    std::ifstream level;
    level.open(filename.c_str(),std::ios::in|std::ios::binary);
    level.seekg(0,std::ios::end);
    length = level.tellg();
    level.seekg(0,std::ios::beg);
    char buffer[length];
    level.read(buffer,length);
    if (buffer[0] == 0x49 && buffer[1] == 0x14)
    {
        char tile_buffer[BYTES_PER_TILE];
        int buffer_place = 1;
        while(buffer_place < length)
        {
            for (int i = 1;i <= BYTES_PER_TILE;i++)
            {
                tile_buffer[i] = buffer[buffer_place+1];
                buffer_place++;
            }
            apply_surface(tile_buffer[1],tile_buffer[2],tiles,screen,&clip[tile_buffer[3]]);
        }
    }
    else
    {
        // File is invalid
        return false;
    }
    level.close();
    return true;
}

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黎夕旧梦 2024-10-02 02:40:57

您的数组处理不正确。
C/C++ 中的数组索引从 0 开始。

您已将“tile_buffer”定义为大小为“BYTES_PER_TILE”的数组。
如果 BYTES_PER_TILE 为 5,则数组将包含元素tile_buffer[0] 到tile_buffer[4]。

在内部 for 循环中,您从 1 循环到 5,因此会发生缓冲区溢出。

我不知道这是否是您问题的原因,但这肯定无济于事。

Your array handling is incorrect.
Array indexing in C/C++ begins from 0.

You have defined 'tile_buffer' to be an array sized 'BYTES_PER_TILE'.
If BYTES_PER_TILE was 5, your array would have elements tile_buffer[0] to tile_buffer[4].

In your inner for-loop you loop from 1 to 5 so a buffer overflow will occur.

I don't know if this is the cause of your problem but it certainly won't help matters.

爱你是孤单的心事 2024-10-02 02:40:57

这可能不是一个答案,但基于 1 的数组处理和不必要的复制让我头疼。

为什么不沿着这些思路做一些事情呢?

if ((length >= 2+BYTES_PER_TILE) && (buf[0] == CONST1) && (buf[1] == CONST2)) {
    for (char *tile = &buf[2]; tile < &buf[length-BYTES_PER_TILE]; tile+=BYTES_PER_TILE) {
        apply_surface(tile[0],tile[1],tiles,screen,&clip[tile[2]]);
    }
}

This is probably not an answer, but the 1-based array handling and the unneeded copying make my head hurt.

Why not just do something along these lines?

if ((length >= 2+BYTES_PER_TILE) && (buf[0] == CONST1) && (buf[1] == CONST2)) {
    for (char *tile = &buf[2]; tile < &buf[length-BYTES_PER_TILE]; tile+=BYTES_PER_TILE) {
        apply_surface(tile[0],tile[1],tiles,screen,&clip[tile[2]]);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文