【问题标题】:How to read in a .cfg.txt file如何读取 .cfg.txt 文件
【发布时间】:2017-05-30 02:29:40
【问题描述】:

一段时间以来,我一直在尝试阅读此文件,并尝试了所有我能想到的东西。我将文件放在我的 Products 文件夹和我的资源文件夹中并包含 (ResourcePath + "File.cfg.txt") 并且都不起作用。如果有人能告诉我我缺少什么以及将这个文件放在哪里以读取它,我将不胜感激。我再次使用 Xcode 和 SFML 库。

Keys.cfg.txt

Window_close 0:0

Fullscreen_toggle 5:89

移动 9:0 24:38

//////////////////////////////////

.CPP

#include "EventManager.h"
using namespace std;

EventManager::EventManager(): m_hasFocus(true){ LoadBindings(); }

EventManager::~EventManager(){
    for (auto &itr : m_bindings){
        delete itr.second;
        itr.second = nullptr;
    }
}

bool EventManager::AddBinding(Binding *l_binding){
    if (m_bindings.find(l_binding->m_name) != m_bindings.end())
        return false;

    return m_bindings.emplace(l_binding->m_name, l_binding).second;
}

bool EventManager::RemoveBinding(std::string l_name){
    auto itr = m_bindings.find(l_name);
    if (itr == m_bindings.end()){ return false; }
    delete itr->second;
    m_bindings.erase(itr);
    return true;
}

void EventManager::SetFocus(const bool& l_focus){ m_hasFocus = l_focus; }

void EventManager::HandleEvent(sf::Event& l_event){
    // Handling SFML events.
    for (auto &b_itr : m_bindings){
        Binding* bind = b_itr.second;
        for (auto &e_itr : bind->m_events){
            EventType sfmlEvent = (EventType)l_event.type;
            if (e_itr.first != sfmlEvent){ continue; }
            if (sfmlEvent == EventType::KeyDown || sfmlEvent == EventType::KeyUp){
                if (e_itr.second.m_code == l_event.key.code){
                    // Matching event/keystroke.
                    // Increase count.
                    if (bind->m_details.m_keyCode != -1){
                        bind->m_details.m_keyCode = e_itr.second.m_code;
                    }
                    ++(bind->c);
                    break;
                }
            } else if (sfmlEvent == EventType::MButtonDown || sfmlEvent == EventType::MButtonUp){
                if (e_itr.second.m_code == l_event.mouseButton.button){
                    // Matching event/keystroke.
                    // Increase count.
                    bind->m_details.m_mouse.x = l_event.mouseButton.x;
                    bind->m_details.m_mouse.y = l_event.mouseButton.y;
                    if (bind->m_details.m_keyCode != -1){
                        bind->m_details.m_keyCode = e_itr.second.m_code;
                    }
                    ++(bind->c);
                    break;
                }
            } else {
                // No need for additional checking.
                if (sfmlEvent == EventType::MouseWheel){
                    bind->m_details.m_mouseWheelDelta = l_event.mouseWheel.delta;
                } else if (sfmlEvent == EventType::WindowResized){
                    bind->m_details.m_size.x = l_event.size.width;
                    bind->m_details.m_size.y = l_event.size.height;
                } else if (sfmlEvent == EventType::TextEntered){
                    bind->m_details.m_textEntered = l_event.text.unicode;
                }
                ++(bind->c);
            }
        }
    }
}

void EventManager::Update(){
    if (!m_hasFocus){ return; }
    for (auto &b_itr : m_bindings){
        Binding* bind = b_itr.second;
        for (auto &e_itr : bind->m_events){
            switch (e_itr.first){
            case(EventType::Keyboard) :
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key(e_itr.second.m_code))){
                    if (bind->m_details.m_keyCode != -1){
                        bind->m_details.m_keyCode = e_itr.second.m_code;
                    }
                    ++(bind->c);
                }
            break;
            case(EventType::Mouse) :
                if (sf::Mouse::isButtonPressed(sf::Mouse::Button(e_itr.second.m_code))){
                    if (bind->m_details.m_keyCode != -1){
                        bind->m_details.m_keyCode = e_itr.second.m_code;
                    }
                    ++(bind->c);
                }
            break;
            case(EventType::Joystick) :
                // Up for expansion.
                break;
            default:
                    break;
            }
        }

        if (bind->m_events.size() == bind->c){
            auto callItr = m_callbacks.find(bind->m_name);
            if(callItr != m_callbacks.end()){
                callItr->second(&bind->m_details);
            }
        }
        bind->c = 0;
        bind->m_details.Clear();
    }
}

void EventManager::LoadBindings(){
    std::string delimiter = ":";

    std::ifstream bindings;
    bindings.open("keys.cfg");
    if (!bindings.is_open()){ std::cout << "! Failed loading keys.cfg." << std::endl; return; }
    std::string line;
    while (std::getline(bindings, line)){
        std::stringstream keystream(line);
        std::string callbackName;
        keystream >> callbackName;
        Binding* bind = new Binding(callbackName);
        while (!keystream.eof()){
            std::string keyval;
            keystream >> keyval;
            int start = 0;
            int end = keyval.find(delimiter);
            if (end == std::string::npos){ delete bind; bind = nullptr; break; }
            EventType type = EventType(stoi(keyval.substr(start, end - start)));
            int code = stoi(keyval.substr(end + delimiter.length(),
                keyval.find(delimiter, end + delimiter.length())));
            EventInfo eventInfo;
            eventInfo.m_code = code;

            bind->BindEvent(type, eventInfo);
        }

        if (!AddBinding(bind)){ delete bind; }
        bind = nullptr;
    }
    bindings.close();
}

【问题讨论】:

    标签: c++ xcode sfml


    【解决方案1】:

    问题是您必须复制捆绑包中的相应文件,并且只有objective-c 才能为您提供目标设备上文件的全名。

    要克服这个问题,请创建一个 .mm 文件并在其中放置一个 c++ trampoline 函数,它会为您提供完整路径(参见下面的代码)。

    一个陷阱可能是您必须确保将"keys.cfg" 等配置文件和文本文件实际复制到包中。选择项目中的相应文件并打开属性检查器;确保 - 检查“目标成员资格”中的相应目标。

    // File: myFileNameProvider.mm
    #import <Foundation/Foundation.h>
    #include <iostream>
    
    std::string GetTextureFilename(const char *name)
    {
        NSString *nameAsNSString = [NSString stringWithUTF8String:name];
        NSString *fullName = [[NSBundle mainBundle]
                              pathForResource:nameAsNSString ofType: nil];
        if (fullName)
            return std::string([fullName UTF8String]);
        else
            return "";
    }
    

    然后,在您的 CPP 代码中,声明std::string GetTextureFilename(const char *name) 的签名,并在打开文件之前调用它获取完整路径:

    // MyCPPFile.cpp
    #include <iostream>
    #include <fstream>
    
    // declaration:
    std::string GetTextureFilename(const char *name);
    
    void myC_Func {
            std::string fullPath = GetTextureFilename("keys.cfg");
            std::ifstream bindings;
            bindings.open(fullPath.c_str());
            if (!bindings.is_open()) {
                std::cout << "! Failed loading keys.cfg." << std::endl;
            }
            ...
    }
    

    【讨论】:

    • 谢谢,我会照做的
    猜你喜欢
    • 1970-01-01
    • 2019-12-30
    • 2022-01-24
    • 2012-12-25
    • 2012-08-11
    • 2010-10-07
    • 2014-04-21
    • 2013-04-17
    • 2015-09-05
    相关资源
    最近更新 更多