Dynamically inserting strings to a std::map
I am trying to create a map of file pairs... First I am searching a specified directory for files using the FindFirstFile and FindNextFile and when a file is found I search the map to see if开发者_JAVA技巧 the associated file is there. If the other file was added to the map, the new found file is inserted beside the previously found one. If an associated file was not found, the new file is inserted to the map and its pair is left intact.
To explain more: lets say we have 2 files file.1.a and file.1 those files represent a pair and thus should be added to the map as a pair
//map<File w/o .a, File w .a>
std::map<CString, CString> g_map;
int EnumerateFiles(LPCTSTR Dir)
{
//Search Files....
//Found a File....(for ex: file.1)
//Append .a to the string and search for it in the map
BOOL bAdded = FALSE;
for(std::map<CString, CString>::iterator itr = g_map.begin(); itr != g_map.end(); itr++)
{
if(StrCmp(tchAssocFile, itr->second) == 0)
{
bAdded = TRUE;
//pair the string with the other one;
}
}
if(!bAdded)
//Add the new string to the map and leave its associate blank
//Do the same in reverse if the associate was found first....
}
I hope this was clear as I can't think of any other way to put it... sry.
Can you please help in solving this issue...
regards
You have two files.
{X} and {X}.a
You want to search some directory space and store which ones you find.
Let us store the information of a find in a std::pair<bool,bool>.
The first value represents if we find {x} the second value represents if we find {X}.a
These pair values are stored in a map using {X} as the index into the map.
#include <memory>
#include <string>
#include <map>
typedef std::pair<bool,bool> FileInfo;
typedef std::map<std::string,FileInfo> FileMapInfo;
FileMapInfo fileMapInfo;
void found(std::string const& fileName)
{
// baseName: We will use this to lookup if either file is found.
// The extension ".a" is removed from this name.
// aExtension: is true if the file ends with ".a"
std::string baseName(fileName);
bool aExtension(false);
std::string::size_type pos = fileName.find_last_of(".a");
if ((pos != std::string::npos) && (pos == fileName.size()-2))
{
// Get the real base
baseName = fileName.substr(0,fileName.size() - 2);
aExtension = true;
}
// This looks up the record about the file(s).
// If it dies not exist it creates an entry with false,false.
FileInfo& fileInfo = fileMapInfo[baseName];
// Now set the appropriate value to true.
if (!aExtension)
{
fileInfo.first = true;
}
else
{
fileInfo.second = true;
}
}
int main()
{
// loop over files.
// call found(<fileName>);
}
If efficiency is an issue, you'd either have to maintain two maps (for both directions of queries, or use a bi-directional map (like this one).
But looking at your problem, I think that two sets ( std::set ), might work better. Into one you put found .a files, into the other the non-a files, and at the end, you take the std::intersection of them :).
I think I would do something like this:
string tchFile = <name of file you just found>;
string tchAssocFile = <name of associated file if it exists, empty otherwise>;
if (tchAssocFile.empty())
g_map[tchFile] = "";
else {
std::map<string, string>::iterator foundAssocIter = g_map.find(tchAssocFile);
if (foundAssocIter != g_map.end())
foundAssocIter->second = tchFile;
else
g_map[tchFile] = tchAssocFile;
}
精彩评论