简体   繁体   中英

Cant find a specific key in my stl container map

Hi I have been racking my head over trying to make my iterator pointer find the specified key for the map stl container. The following project is for my parser excercise where we are given a file and the point is to parse through it and read each line by line. The file is supposed to be in the project folder to be read. The file has the following text

[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

and we are supposed to make a Mapkey that's a combination of section (which is the text in brackets) and "|" and key (that is the text before the =), the value is the text after the equals sign.

I have code that works up until I try to use the find function to find the Mapkey specified. Can someone help??

#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);
    }

I will be grateful for any help. Thanks

I don't know what exactly was the problem. However, I have changed the way it parse the words and now its working. Following is the output:

#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();
}

One thing you could do is, move your debugger part after you saved all keys and values to map. ie after closing the file.

UPDATE :

I did debugged your code; followings are the result or logical problems in your while (!myFile.eof()){....}

  1. Your code do not combine section + key before inserting in to the map. Because your condition to insert to map is weak( if (key != "") is weak). This result to insert some wrong keys to be inserted with "" values. Therefore instead of that, use this: if (key.size() != 0 && value.size() != 0) like I made in my implementation.

  2. The parsing section in the both if (strLine.find("=") != -1) , have a bug, that they save key and values to the map as follows:

    "settings|fullscreen " " true" -->> In your code ( with space )

    "settings|fullscreen" "true" -->> Actually needed

This happens for all your inputs. 这是图像视图 . As long as you do not change the code inside while (!myFile.eof()){....} as follows, you can not look for the key iter = m_mapPairs.find("settings|windowWidth"); .

Here is the fixed solution :

#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);
}

Hope this was helpful.

Your map "m_mapPairs" contains space at the end of the key "settings|windowWidth ". However, the key that you are passing to find does not contain a space at the end. That's why find is not successful.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM