Problems with std::map
-
This is my first experience with maps and I am having some troubles. I have developed a Logger that can do private logs depending on the client who calls the COM object. Based on the client's information, it needs to find the specific file to log to. Here is my code: //(header declarations) std::map m_FileList; std::map::iterator mFileListIterator; //(code) bool ClientHasCalledBefore; _bstr_t FileName; //name of the file coming in. //Look for FileName in map to see if it was called before. ClientHasCalledBefore = (!(m_FileList.find(FileName) == m_FileList.end())); // If it has called before, it logs to a clear file. // If not, it creates the file, then appends the logs. if (!ClientHasCalledBefore) { ofstream *ofstr = new ofstream(FileName, ios::out); m_FileList[FileName] = ofstr; *m_FileList[FileName] << "EntryToBeLogged"; m_FileList[FileName]->close(); } else { m_FileList[FileName]->open(FileName, ios::app); *m_FileList[FileName] << "EntryToBeLogged"; m_FileList[FileName]->close(); } Okay. This code leads me to my first question. When I enter a new file into the map, sometimes it does not enter properly and the next time the conditional is checked, the FileName is not found. It does this sometimes the first one to three times it runs through. After the first couple of times, everything works fine. Because I am opening the file clean, this overwrites the first couple of entries. Any suggestions so that my conditional finds the entry in the map the first time? //************** In my destructor, I have this code to add a footer to every file: for (m_FileListIterator = m_FileList.begin(); m_FileListIterator != m_FileList.end(); ++m_FileListIterator) { (m_FileListIterator->second)->open(FileListIterator->first, ios::app); *(m_FileListIterator->second) << "FooterToBeAdded"; (m_FileListIterator->second)->close(); } I think something is totally flawed with this. Sometimes it will append to a file I would have never created in my code, making a new file. Other times it will log the footer into the same file multiple times. It is almost as if it is not iterating. Again, this is my first experience with any of this. Any help is much appreciated. Thank you.
-
This is my first experience with maps and I am having some troubles. I have developed a Logger that can do private logs depending on the client who calls the COM object. Based on the client's information, it needs to find the specific file to log to. Here is my code: //(header declarations) std::map m_FileList; std::map::iterator mFileListIterator; //(code) bool ClientHasCalledBefore; _bstr_t FileName; //name of the file coming in. //Look for FileName in map to see if it was called before. ClientHasCalledBefore = (!(m_FileList.find(FileName) == m_FileList.end())); // If it has called before, it logs to a clear file. // If not, it creates the file, then appends the logs. if (!ClientHasCalledBefore) { ofstream *ofstr = new ofstream(FileName, ios::out); m_FileList[FileName] = ofstr; *m_FileList[FileName] << "EntryToBeLogged"; m_FileList[FileName]->close(); } else { m_FileList[FileName]->open(FileName, ios::app); *m_FileList[FileName] << "EntryToBeLogged"; m_FileList[FileName]->close(); } Okay. This code leads me to my first question. When I enter a new file into the map, sometimes it does not enter properly and the next time the conditional is checked, the FileName is not found. It does this sometimes the first one to three times it runs through. After the first couple of times, everything works fine. Because I am opening the file clean, this overwrites the first couple of entries. Any suggestions so that my conditional finds the entry in the map the first time? //************** In my destructor, I have this code to add a footer to every file: for (m_FileListIterator = m_FileList.begin(); m_FileListIterator != m_FileList.end(); ++m_FileListIterator) { (m_FileListIterator->second)->open(FileListIterator->first, ios::app); *(m_FileListIterator->second) << "FooterToBeAdded"; (m_FileListIterator->second)->close(); } I think something is totally flawed with this. Sometimes it will append to a file I would have never created in my code, making a new file. Other times it will log the footer into the same file multiple times. It is almost as if it is not iterating. Again, this is my first experience with any of this. Any help is much appreciated. Thank you.
Hello ChemmieBro, next time you post here please make sure you check on the "Do not treat <'s as HTML tags" checkbox below the input window: otherwise your
<
's and>
's won't show up properly. For the benefit of other readers, I'm reproducing here the definition ofm_FileList
with the bracket thing right:std::map<BSTR, ofstream*> m_FileList;
The problem you're having is most likely the following: when you look up an item in
std::map
, the key you pass is compared against those of the elements stored in the map. So far so good, but in your case it isBSTR
s that are used as keys, and these are pointers: so, instead of comparing the contents pointed to by theBSTR
, it is the pointer addresses thatstd::map
is taking into account, certainly not what you want. The most straightforward solution is to use as keys another type of objects with the right comparison semantics, like for instance MFCCString
or some other wrapper around rawBSTR
s. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo Want a Boost forum in Code Project? Vote here[^]! -
Hello ChemmieBro, next time you post here please make sure you check on the "Do not treat <'s as HTML tags" checkbox below the input window: otherwise your
<
's and>
's won't show up properly. For the benefit of other readers, I'm reproducing here the definition ofm_FileList
with the bracket thing right:std::map<BSTR, ofstream*> m_FileList;
The problem you're having is most likely the following: when you look up an item in
std::map
, the key you pass is compared against those of the elements stored in the map. So far so good, but in your case it isBSTR
s that are used as keys, and these are pointers: so, instead of comparing the contents pointed to by theBSTR
, it is the pointer addresses thatstd::map
is taking into account, certainly not what you want. The most straightforward solution is to use as keys another type of objects with the right comparison semantics, like for instance MFCCString
or some other wrapper around rawBSTR
s. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo Want a Boost forum in Code Project? Vote here[^]!Thanks for your help. I'm brand new to using BSTRs also. I do not have access to MFC here, so the CString is out. I will look into using some kind of wrapper around the BSTRs.
-
Thanks for your help. I'm brand new to using BSTRs also. I do not have access to MFC here, so the CString is out. I will look into using some kind of wrapper around the BSTRs.
Check Michael Dunn and Nishant Sivakumar's Complete Guide to C++ Strings, Part II [^], you might find what you need there. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo Want a Boost forum in Code Project? Vote here[^]!
-
Check Michael Dunn and Nishant Sivakumar's Complete Guide to C++ Strings, Part II [^], you might find what you need there. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo Want a Boost forum in Code Project? Vote here[^]!
Thank you so much. It was a pretty simple fix using the _bstr_t class instead of the BSTR. My inexperience with BSTR and _bstr_t got the best of me. I don't know why I chose BSTR in my map instead of _bstr_t. But everything is working fine now!