Reputation: 169
In a puzzle in CodinGame called MIME Type, we're asked to make a program that:
I was able to solve this puzzle. My first attempt, that I present here, is more complicated. I'm posting it in this question, however, because I had a weird bug and I couldn't figure out what was the reason behind it.
Consider the following file ("MIME.dat") that contains extensions and their corresponding MIME types:
html
text/html
png
image/png
gif
image/gif
Consider as well the following file ("names.dat) that contains the name of the files:
animated.gIf
portrait.png
index.html
The expected output is (following the order by which the names appear in the file):
image/gif
image/png
text/html
Here's my code:
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <cstdlib>
using namespace std;
struct cmp_ins {
bool operator()(const string& s1, const string& s2) const
{
if(s1.length()!=s2.length())
return false;
else
{
bool b=true;
string::const_iterator i,j;
for(i=s1.begin(), j=s2.begin(); b && i!=s1.end();++i,++j)
{
if((isalpha(*i) && isalpha(*j)) && (toupper(*i)!=toupper(*j)))
b=false;
else if((isalpha(*i) && !isalpha(*j)) || (!isalpha(*i) && isalpha(*j)))
b=false;
else if((!isalpha(*i) && !isalpha(*j)) && *i!=*j)
b=false;
}
return b;
}
}
};
int main()
{
try
{
map<string,string,cmp_ins> db;
string name,MT;
string::iterator j;
ifstream fdb("MIME.dat"), fn("names.dat");
if(!fdb.is_open())
throw runtime_error("Couldn't open MIME.dat");
if(!fn.is_open())
throw runtime_error("Couldn't open names.dat");
struct cmp_ins obj;//Will be used to verify if cmp_ins works correctly
while(fdb >> name >> MT)
{
db[name]=MT;
cout << "(" << name << "," << MT << ")" << endl;
}
cout << endl;
fdb.close();
while(fn >> name)
{
cout << "name:" << name << endl;
for(j=name.end();*j!='.' && j!=name.begin();--j);
if(*j!='.')
cout << "UNKNOWN" << endl;
else
{
string ac=name.substr(j-name.begin()+1,name.end()-j);
cout << ac << "=gif? " << obj(ac,string("gif")) << endl;
map<string,string,cmp_ins>::iterator t=db.find(ac);
cout << "MIME: ";
if(t==db.end())
cout << "UNKNOWN" << endl;
else
cout << t->second << endl;
}
cout << endl;
}
fn.close();
return EXIT_SUCCESS;
}
catch(exception& e)
{
cerr << e.what() << endl;
return EXIT_FAILURE;
}
}
Here's the output:
(html,text/html)
(png,image/png)
(gif,image/gif)
name:animated.gIf
gIf=gif? 1
MIME: image/gif
name:portrait.png
png=gif? 0
MIME: image/gif
name:index.html
html=gif? 0
MIME: UNKNOWN
As you can see, the program considers "portrait.png" as an image/gif file, while png!= gif, and the function cmp_ins was able to tell the difference (it return 0). Also, the program wasn't able to recognize the type of "index.html".
Could you please tell me what's wrong?
Upvotes: 1
Views: 687
Reputation: 44238
For your comparator to be used with std::map
it must satisfy Compare concept:
The return value of the function call operation applied to an object of type Compare, when contextually converted to bool, yields true if the first argument of the call appears before the second in the strict weak ordering relation induced by this Compare type, and false otherwise.
Your comparator seems to return true if objects equal, which is not what required by this concept. You need to rewrite it to satisfy "strict weak ordering relation"
Upvotes: 2