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()){....}
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.
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.