patterncppMinor
Iterate over a file multiple times
Viewed 0 times
fileiteratemultipletimesover
Problem
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:
but I feel like reloading the file into memory every time is redundant. Is there anything that could be improved?
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?
Solution
Slightly better way:
If improvement is based on this statement, then something like
Best way:
Roughly this:
Some edge cases:
There might be duplications in the first file, so it will require first adding into
candidates.close(); //I know theres better than thisIf improvement is based on this statement, then something like
stringstream would be good fit.Best way:
std::map 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 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.Code Snippets
candidates.close(); //I know theres better than thisstd::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';
}
}Context
StackExchange Code Review Q#156712, answer score: 2
Revisions (0)
No revisions yet.