如何读取.cfg.txt文件

时间:2017-01-14 23:48:20

标签: c++ xcode sfml

我一直试图阅读这个文件一段时间,并尝试了我能想到的一切。我将文件放在我的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();
}

1 个答案:

答案 0 :(得分:1)

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

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

一个缺陷可能是您必须确保将"keys.cfg"之类的配置文本文件实际复制到捆绑包中。在项目中选择相应的文件,然后打开属性检查器;确保 - 目标会员资格中的相应目标&#34;检查。

// 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;
        }
        ...
}