C / C ++有没有使用相对路径的跨平台方式?

时间:2010-12-22 05:13:41

标签: c++ cross-platform sdl relative-path

我正在用SDL编写一个小游戏,文件结构如下:

“src / game /”同时包含.h和.cpp源文件。

“data /”包含地图,瓷砖,精灵等游戏文件......

例如,

加载精灵我将使用以下代码。

spriteLib.loadSprite("data/sprites/sprite-ghost.bmp");

将此字符串转换为绝对路径我在函数的前4行中包含这些行:

SSprite CSpriteLib::loadSprite(std::string file)
{
    //Converting the file path
    char converted[128];
    realpath(file.c_str(),converted);
    file = converted;

但是这样程序只能在liux下编译......所以如果有人知道另一种方法,我会很感激。

4 个答案:

答案 0 :(得分:5)

Boost是你的朋友。这是Boost Filesystem教程的链接。

答案 1 :(得分:3)

几点:

char converted[128];
realpath(file.c_str(),converted);
  1. 首先,某些操作系统(Solaris)上的realpath仍可能返回相对路径。
  2. 您的代码包含缓冲区溢出,最好使用canonicalize_file_namechar *m=realpath(file.c_str(),0); ... free(m); - 但这是特定于Linux的。请参阅man realpath,了解如何正确使用它。
  3. 另外,realpath如何帮助您打开数据?如果

    fopen(converted,"r")
    

    适用于您的情况

    fopen(file.c_str(),"r")
    

    也可以。它用于帮助删除所有符号链接等。

    如果您需要与realpath类似的功能,可以在Windows下使用GetFullPathName,但是 它的行为仍然不同。

答案 2 :(得分:1)

刚为它写了一个小课:

#include <string>
#include <vector>
#include <iostream>

class CFilePath
{
        typedef std::vector<std::string> TPath;
    public:
        enum EPlatform
        {  
            Windows,
            Unix
        };
        CFilePath(EPlatform p_platform) : m_platform(p_platform) {}
        CFilePath& operator/(const char* p_path)
        {  
            m_path.push_back(p_path);
            return *this;
        }

        std::string GetPath()
        {  
            std::string ret;
            if (m_path.empty())
                return ret;
            for (unsigned i = 0; i < m_path.size();)
            {
                ret+=m_path[i];
                i++;
                if (i < m_path.size())
                {  
                    switch (m_platform)
                    {  
                        case Windows:
                            ret+="\\";
                            break;
                        case Unix:
                            ret+="/";
                            break;
                    }
                }
            }
            return ret;
        }
        operator const char*()
        {
            return GetPath().c_str();
        }
        EPlatform m_platform;

    private:
        std::vector<std::string> m_path;
};

int main(int argc, char* argv[])
{
    CFilePath::EPlatform platform = CFilePath::Windows; // variable
    CFilePath path(platform);
    path/"data"/"sprites"/"sprite-ghost.bmp";
    std::cout << path << std::endl;
    path.m_platform = CFilePath::Unix;
    std::cout << path << std::endl;

    return 0;
}

会打印:

data\sprites\sprite-ghost.bmp
data/sprites/sprite-ghost.bmp

答案 3 :(得分:0)

我的建议是:首先,您的主程序应接受本机文件名作为参数,表示程序数据的存在位置,例如

C:\program files\mycompany\mygame

这将决定使用哪些数据的责任传递给其他程序(例如bash脚本或驱动程序或其他程序)。

其次,使用 unix 格式的数据定义目录空间的子部分,以便程序中的所有文件名文字都具有此格式。没有ifs和buts,总是Unix。例如:

spriteLib.loadSprite("data/sprites/sprite-ghost.bmp");

现在编写一个函数,它将传入的目录名(原生格式)与转换为本机格式的unix文件名相结合,以获得适合访问的文件名。您已尝试执行此操作,但您正在使用操作系统相关功能。别。自己写吧。你想要解决这个问题:

C:\program files\mycompany\mygame\data\sprites\sprite-ghost.bmp

@ Industrial-antidepressant(以前是@nice金发愚蠢的女孩)的方法也很好,但它的工作量更多。