Aim of the code is to print all of the strings from one file that match strings from another file. Names of both of the files are provided by command line arguments.
Code:
int main(int argc, char *argv[]){
ifstream answers(argv[1]);
ifstream candidates(argv[2]);
for (string s; getline(answers,s);){
for (string h; getline(candidates,h);){
if (!s.compare(h)){
cout << h << ":" << s << endl;
}
}
candidates.close(); //I know theres better than this
candidates.open(argv[2], ios::in);
}
}
but I feel like reloading the file into memory every time is redundant. Is there anything that could be improved?
1 Answer 1
Slightly better way:
candidates.close(); //I know theres better than this
If improvement is based on this statement, then something like stringstream
would be good fit.
Best way:
std::map<std::string, std::size_t>
will fit the job nicely. After you've done with it, just iterate through and see if anything has counter equal to 2 or higher, and print those.
Roughly this:
std::map<std::string, std::size_t> appearance_count;
while (std::getline(answers, s))
{
++appearance_count[s];
}
while (std::getline(candidates, s))
{
++appearance_count[s];
}
for (const auto& reading: appearance_count)
{
if (reading.second > 1)
{
std::cout << reading.first << '\n';
}
}
Some edge cases:
There might be duplications in the first file, so it will require first adding into std::set
, then adding to the map. Second file is unaffected by that, since any string with appearance count larger than 1 is already wanted. Though if the second file contains duplicates as well, you'll need two sets.
-
\$\begingroup\$ Hey! this looks promising! will try it right now. sorry again, bug caused when moving code here. \$\endgroup\$John– John2017年03月02日 15:22:17 +00:00Commented Mar 2, 2017 at 15:22
-
\$\begingroup\$ @John, don't expect it to be working like a charm :) I've written it right into the answer box, so it might not even compile. In the future, just copy paste, highlight, hit ctrl-k. It will format it for you. \$\endgroup\$Incomputable– Incomputable2017年03月02日 15:23:01 +00:00Commented Mar 2, 2017 at 15:23
-
\$\begingroup\$ tanks for the ctrl-k tip! by the way, this thing is super fast! its great! now, I am trying to do a hash lookup table. so what I am comparing is md5(candidates) vs answers. is there a way I could store md5(candidates):candidates ie. as to know what was the plaintext? \$\endgroup\$John– John2017年03月02日 15:54:10 +00:00Commented Mar 2, 2017 at 15:54
-
\$\begingroup\$ @John Sorry, but what you say doesn't make any sense to me. I believe there is
std::unordered_map
, which is a hashmap. So you hash every string, not a file. \$\endgroup\$Incomputable– Incomputable2017年03月02日 15:58:26 +00:00Commented Mar 2, 2017 at 15:58 -
\$\begingroup\$ lets say I have a file full of md5 hashes, and a file full of words. I want to know what hash = md5(word). \$\endgroup\$John– John2017年03月02日 16:00:34 +00:00Commented Mar 2, 2017 at 16:00
if (!h.compare(h))
, which is false all the time. \$\endgroup\$