【问题标题】:Cant find a specific key in my stl container map在我的 stl 容器映射中找不到特定键
【发布时间】:2018-04-09 12:53:58
【问题描述】:

嗨,我一直在努力让我的迭代器指针找到 map stl 容器的指定键。以下项目用于我的解析器练习,我们得到一个文件,重点是解析它并逐行读取。该文件应该位于要读取的项目文件夹中。 该文件具有以下文本

[settings]

;this is the settings section

fullscreen = true

gamepad = false

windowWidth = 800

windowHeight = 600

[levels]

numLevels = 3

Level1 = file1.lvl

Level2= file2.lvl

Level3=file3.lvl

[player]

name = Student

speed = 5.0

[enemy]

name ="Zombie"

speed = 1.0

我们应该创建一个 Mapkey,它是部分(括号中的文本)和“|”的组合和key(即=之前的文本),value是等号之后的文本。

在我尝试使用 find 函数查找指定的 Mapkey 之前,我的代码可以正常工作。有人可以帮忙吗?

#include <iostream>
#include <fstream> 
#include <string>
#include <map>
#include <algorithm>
using namespace std;

std::map<std::string, std::string> m_mapPairs;



int main()
    {
        string strLine;
        fstream myFile;


        myFile.open("New Text Document.txt"); //name of the file to be read
        if (myFile.is_open())
        {
            static string section = " ";
            string key = " ";
            string value= " ";
            while (!myFile.eof())
            {

                    getline(myFile, strLine);
                    if (strLine.find("[") !=-1) 
                    {
                        int index1 = strLine.find_first_of("[");    //finds it in a line, if it does it puts it in index 1 if it doesnt it doesnt bother
                        int index2 = strLine.find_first_of("]");//finds it in a line, if it does it puts it in index 2 if it doesnt it doesnt bother
                         section = strLine.substr(index1 + 1, index2 - 1);
                         section = section + "|";

                    }
                    if (strLine.find("=") != -1)
                    {
                        int index1 = strLine.find("");
                        int index2 = strLine.find("=");
                        key = strLine.substr(index1, index2 );

                    }
                    if (strLine.find("=")!=-1 )
                    {
                        int index1 = strLine.find("="); //finds it in a line, if it does it puts it in index 1 if it doesnt it doesnt bother
                        value = strLine.substr(index1+1 , 11);

                    }

                    if (strLine.find(";") > -1)
                    {
                        int index1 = strLine.find(";"); //finds it in a line, if it does it puts it in index 1 if it doesnt it doesnt bother
                        string ivalue = strLine.substr(index1 + 1, 11);

                    }
                    if (key != "") {

                        std::string Thekey = section + key;
                        m_mapPairs.insert(std::pair<std::string, std::string>(Thekey, value));
                    }
            }


            std::map<std::string, std::string>::iterator iter;      //iterating through all the keys
            iter = m_mapPairs.begin();
            while (iter != m_mapPairs.end())
            {


                std::cout << iter->first << "\'s value is ";
                std::cout << iter->second << std::endl;
                iter++;

            }



            iter = m_mapPairs.find("settings|windowWidth");     //trying to find this key in the map but cant find it

            if (iter != m_mapPairs.end())
            {
                std::cout << "found: " << std::endl;
                return true;
            }
            else
            {
                return false;
            }


            myFile.close();
        }



        int a;
        std::cin >> a;
        return (0);
    }

如果有任何帮助,我将不胜感激。 谢谢

【问题讨论】:

  • 不是问题,但static string section = " "; 可以是string section;
  • 与您的问题更相关,您能否尝试向我们展示输入文件的较小部分,然后显示您的程序的预期输出和实际输出(使用较小的输入集)?你试过to debug your program
  • 看起来问题是您在创建的字符串的末尾留下了试用空格。使用调试器单步执行您的代码以进行确认。如果您是,您将需要编写一个修剪函数或更改解析行的方式。
  • @Someprogrammerdude 嘿,它看起来应该和 je​​jos 控制台上的东西一模一样。

标签: c++ dictionary stl find containers


【解决方案1】:

我不知道到底是什么问题。但是,我已经改变了它解析单词的方式,现在它的工作方式。以下是输出:

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>

int main()
{
    std::map<std::string, std::string> m_mapPairs;
    std::string strLine;
    std::fstream myFile;
    myFile.open("New Text Document.txt"); //name of the file to be read

    if (myFile.is_open())
    {
        std::string section; section.clear();
        std::string key;     key.clear();
        std::string value;   value.clear();
        while (!myFile.eof())
        {
            getline(myFile, strLine);

            if (strLine[0] == '[' && strLine[strLine.size() - 1] == ']')
            {
                section.clear();
                int index2 = strLine.find_first_of("]");
                section = strLine.substr(1, index2 - 1);
                section += "|";
                continue;
            }
            if (strLine[0] == ';') continue;

            std::string tempStore; tempStore.clear();
            for (size_t i = 0; i < strLine.size(); ++i)
            {
                if (strLine[i] != ' ' && strLine[i] != '=')
                    tempStore += strLine[i];
                if (strLine[i] == ' ' && strLine[i + 1] == '=')
                {
                    key = section + tempStore;
                    tempStore.clear();
                }
                if (i + 1 == strLine.size())
                    value = tempStore;
            }

            if (key.size() != 0 && value.size() != 0)
            {
                m_mapPairs[key] = value;
                key.clear();
                value.clear();
            }
        }
        myFile.close();
    }

    if (m_mapPairs.size() != 0)
        for (const auto& it : m_mapPairs)
            std::cout << it.first << " 's Value: \t" << it.second << std::endl;

    std::cout << std::endl;

    if(m_mapPairs.find("settings|windowWidth") != m_mapPairs.end())
        std::cout << "found! " << std::endl;
    else
        std::cout << "Not found! " << std::endl;

    std::cin.get();
}

您可以做的一件事是,在将所有键和值保存到映射后移动调试器部分。即关闭文件后。

更新

我确实调试了你的代码;以下是结果或逻辑 while (!myFile.eof()){....} 中的问题

  1. 在插入地图之前,您的代码未组合 section + key。因为您插入地图的条件很弱(if (key != "") 很弱)。这个结果插入了一些错误的键,用"" 值插入。因此,请改用这个:if (key.size() != 0 &amp;&amp; value.size() != 0),就像我在实现中所做的那样。

  2. if (strLine.find("=") != -1) 中的解析部分都有一个错误,它们将键和值保存到映射中,如下所示:

    "settings|fullscreen " " true" -->> 在您的代码中带空格

    "settings|fullscreen" "true" -->> 实际需要

您的所有输入都会发生这种情况。 。只要不改(!myFile.eof()){....}里面的代码如下,就可以不找keyiter = m_mapPairs.find("settings|windowWidth");

这里是固定的解决方案

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

std::map<std::string, std::string> m_mapPairs;
int main()
{
    string strLine;
    fstream myFile;


    myFile.open("New Text Document.txt"); //name of the file to be read
    if (myFile.is_open())
    {
        static string section = "";
        string key = "";
        string value = "";

        while (!myFile.eof())
        {
            getline(myFile, strLine);
            if (strLine.find("[") != -1)
            {
                int index1 = strLine.find_first_of("[");   
                int index2 = strLine.find_first_of("]");
                section = strLine.substr(index1 + 1, index2 - 1);
                section = section + "|";
            }
            if (strLine.find("=") != -1)
            {
                int index1 = strLine.find("");
                int index2 = strLine.find("=");
                //change in following line
                key = strLine.substr(index1, index2-1);
            }
            if (strLine.find("=") != -1)
            {
                int index1 = strLine.find("=");
                //change in following line
                value = strLine.substr(index1 + 2, strLine.size()-1);
            }
            if (strLine.find(";") > -1)
            {
                int index1 = strLine.find(";"); 
                string ivalue = strLine.substr(index1 + 1, 11);
            }
            //change in following line
            if (key.size() != 0 && value.size() != 0)
            {
                std::string Thekey = section + key;
                m_mapPairs.insert(std::pair<std::string, std::string>(Thekey, value));
            }
        }
        myFile.close();
    }

    std::map<std::string, std::string>::iterator iter;      //iterating through all the keys
    iter = m_mapPairs.begin();
    while (iter != m_mapPairs.end())
    {
        std::cout << iter->first << "\t Value: ";
        std::cout << iter->second << std::endl;
        iter++;
    }

    iter = m_mapPairs.find("settings|windowWidth");     //trying to find this key in the map but cant find it

    if (iter != m_mapPairs.end())
    {
        std::cout << "found ! " << std::endl;
    }
    else
    {
        std::cout << "NOT found: " << std::endl;
    }

    std::cin.get();//return (0);
}

希望这对您有所帮助。

【讨论】:

  • Jejo 是的,我查看了您的代码。但我需要使用我的代码来实现它。我仍然不知道我的有什么问题。不过我会看看它。
  • 嘿,jejo,我尝试了你建议我做的所有事情,但我没有在 while (!myFile.eof()){....} 中更改任何内容。因为我不想改变那部分,但是在做了你要求我做的所有事情之后,我仍然发现自己遇到了同样的问题。
  • 你如何修复代码以获得没有“”的僵尸??
  • 因为如果你运行代码会发生什么僵尸会变成僵尸“。这不是我想要的。我想要没有“”
【解决方案2】:

您的地图“m_mapPairs”在键的末尾包含空格 “设置|窗口宽度”。但是,您传递给 find 的键末尾不包含空格。这就是 find 不成功的原因。

-->m_mapPairs.find("settings|windowWidth").

【讨论】:

  • 你检查过使用 --> iter = m_mapPairs.find("settings|windowWidth "); //注意传递给find的键在末尾包含一个空格
猜你喜欢
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多