如何在.cfg.txt文件中读取

How to read in a .cfg.txt file

本文关键字:文件 读取 txt cfg      更新时间:2023-10-16

我一直在尝试阅读这个文件一段时间,并尝试了我能想到的一切。我将文件放在我的产品文件夹和我的资源文件夹中并包含(资源路径 + "文件.cfg.txt"),但两者都不起作用。如果有人能告诉我我缺少什么以及将这个文件放在哪里阅读它,我将不胜感激。我再次使用Xcode和SFML库。

钥匙.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();
}

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

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

一个陷阱可能是您必须确保像"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;
        }
        ...
}