Public Group

# Cannot print out map items.

This topic is 2860 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

So i'm trying to make a config reader and it reads all sections , keys, values . When i try to put the data in a map<string, pair<string, string> > and print it out , the console gives an output: Segmentation fault.

the code:
SectionData::iterator coniter;    in.open( cpath_.c_str( ) );    if( in.fail( ) )        throw "Failed to open file [ " + cpath_ + " ]\n";        string Line, section, key, data;    if( in.is_open( ) )    {        while( !in.eof( ) ){                bool has_sections = false;        bool lineIsSection = false;        getline(in, Line);           /* Skip empty lines and lines begining with '#'            * To skip lines in the config file just put '#' in front of            * the line. that will make the handler skip the line            */	  if(Line.empty( ) || Line[0] == '#')		continue;              //remove new lines and partialy new lines               rebuild_string(Line, "\r");               rebuild_string(Line, "\n");              if(exist("[", Line) && exist("]", Line))              {                  std::cout << "Section found\n" << std::endl;                  has_sections = true;                  lineIsSection = true;              }else{                  lineIsSection = false;              }              if(has_sections && lineIsSection)               {                      SectionStart = find("[", Line );                      SectionEnd   = find("]", Line);                      section = Line.substr(SectionStart +1 , SectionEnd - SectionStart -1);                                                               continue;               }                       Split      = find("=", Line );             KeyStart   = find_first_not_empty(Line);             KeyEnd     = find_first_not_of("=", Line, KeyStart);             ValueStart = find_first_not_empty(Line, Split+1 );             ValueEnd   = Line.size( );                        key = Line.substr( KeyStart, KeyEnd - KeyStart );            data = Line.substr( ValueStart, ValueEnd - ValueStart);            //remove all empty spaces from the strings to prevent invalid results            section = rebuild_string(section, " ");            key = rebuild_string(key, " ");            data = rebuild_string(data, " ");                       SectionContents[section] = std::make_pair(key, data);                   }        SectionContents.begin();        while (coniter != SectionContents.end())        {            std::cout << "Key [ " << coniter->first << " ]\n";        coniter++;        }    }    //Close the file    in.close( );

Here is a cfg prototype
[section1]Key1 = 0xF36DKey2 = 0x1337Key3 = 0xFDA4Key4 = 0x87LD[section2]default=config.cfg

SectionContents is a typedef of my map type
and the rest of the values are defined in my class. Hope u could help out.

##### Share on other sites
You don't initialise your iterator coniter anywhere. Above the output loop you have the line SectionContents.begin(); which doesn't do anything by itself.

I guess this should be

coniter = SectionContents.begin();

##### Share on other sites
Thanks, now it prints them, but if i could ask 1 more thing, it stores only 1 value per section. eg

[section1]Key10xF36D[section2]defaultconfig.cfg

my goal was to store all by they're sections .. if it's not too much to ask could u point out the bug :/ i don't seem to find it.

##### Share on other sites
A map allows a key only once. You use the section as key. As soon as a new entry for a section is inserted the old one is gone.

You should either munge section and key in one string (doesn't feel too clean) or make a std::map<std::string,std::map<std::string,std::string> > (note the space between the ending brackets).

This allows to do this:

SectionContents[section][key] = data;

##### Share on other sites
Isn't the map<> a multi dimensional array ? Doesn't it allow a function like push back the vector's .pushback . The basic reason i used map is so i can have 1 section with multiple keys paired with the data assigned to them. The idea was given to me by pushedx , but since i have never used map it's a tough task but i will continue to try. Thanks for your help.

##### Share on other sites
Quote:
 Original post by EndurionA map allows a key only once. You use the section as key. As soon as a new entry for a section is inserted the old one is gone.You should either munge section and key in one string (doesn't feel too clean) or make a std::map > (note the space between the ending brackets).This allows to do this:SectionContents[section][key] = data;

Or simply use a multimap :)

##### Share on other sites
Do not use .eof() to control your loop. It doesn't do what you want.

Quote:
 Original post by Cha0sBGIsn't the map<> a multi dimensional array ?

No; it's an associative array.

Quote:
 Doesn't it allow a function like push back the vector's .pushback .

No, because .push_back means "put this at the end", and the contents of a map must be sorted, and the thing you're inserting might not logically belong at the end.

But having a .push_back does not make things multi-dimensional anyway.

Quote:
 The basic reason i used map is so i can have 1 section with multiple keys paired with the data assigned to them.

Yes; so you have section-contents that are a mapping from key to value, and then the whole file is represented with a mapping from section-name to section-contents. So you make a map of maps. No problem.

A multimap would work, but nesting the maps lets you get values by just indexing twice - by section-name and then by key. This is more likely to be what you want (as opposed to looking up a section-name, and then iterating through a bunch of string-pairs to find the data you want).

##### Share on other sites
The .eof does the job of looping trough the contents of the config file. But for the map container ... i don't know i'll have to find some tutorials on multi-maps and figure it out on my own. I already asked way to much from you guys , and u have helped me a lot, for that i'm grateful.

##### Share on other sites
Quote:
 Original post by Cha0sBGThe .eof does the job of looping trough the contents of the config file.

Not exactly. Zahlman's a smart guy, he knows what he is talking about and he would not have mentioned it were it not important.

std::istream::eof() is only set after a failed read attempt. This is so that the stream does not have to try "look-ahead" to see if the end has been reached. However, this also means that a naive loop-until-eof will read an extra, invalid element.

As Zahlman's link states, it is both more correct and easier (if a little less intuitive at first) to use the read condition itself as the loop condition:
while(getline(in, Line)) {   // ...}

Quote:
 But for the map container ... i don't know i'll have to find some tutorials on multi-maps and figure it out on my own. I already asked way to much from you guys , and u have helped me a lot, for that i'm grateful.

SGI's site is usually a decent place to start for the standard containers: mutlimap

##### Share on other sites
Well the issue with the multi-map is that i don't know if it's linux compatible , because it doesn't want to comple. Gives some not defined stuff .. And i'm sure it's in the <map> include and i've got it included so i don't know what the problem here is.

• 18
• 11
• 16
• 9
• 49
• ### Forum Statistics

• Total Topics
631397
• Total Posts
2999783
×