Reputation: 127
I want to be able to a string that contains certain characters in a file that contains one string per line.
#include <iostream>
#include <fstream>
#include <string>
int main(){
string line;
ifstream infile;
infile.open("words.txt");
while(getline(infile, line,' ')){
if(line.find('z')){
cout << line;
}
}
}
That's my attempt at finding all the string that contains the character z
.
The text file contains random strings such as
fhwaofhz
cbnooeht
rhowhrj
perwqreh
dsladsap
zpuaszu
so with my implementation, it should only print out the strings with the character z
in it. However, it seems to be reprinting out all the contents from the text file again.
Upvotes: 0
Views: 1110
Reputation: 908
Problem:
In your file the strings aren't separated by a space (' '
) which is the end delimiter, they are separated by a end of line ('\n'
), that is a different character. As a consequence, in the first getline
everything goes to line
. line
contains all the text in the file, including z's, so all the content is printed. Finally, the code exits the while
block after running once because getline
reaches the end of the file and fails.
If you run this code
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile, line,' ')){
std::cout << "Hi";
if(line.find('z')){
std::cout << line;
}
}
}
"Hi" will be only printed once. That is because the while
block is only executed once.
Additionaly, see that line.find('z')
won't return 0 if not match is found, it will return npos
. See it running this code (As it says here):
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile,line)){
std::cout << line.find('z');
if(line.find('z')){
std::cout << line << "\n";
}
}
}
Solution:
Use getline(infile,line)
that is more suitable for this case and replace if(line.find('z'))
with if(line.find('z') != line.npos)
.
while(getline(infile,line)){
if(line.find('z') != line.npos){
std::cout << line << "\n";
}
}
If you need to put more than one string per line you can use the operator >>
of ifstream
.
Additional information:
string
, cout
and ifstream
are in the namespace std
. Probably it was a part of a longer file where you were using using namespace std;
. If that is the case, consider that it is a bad practice (More info here).Full code:
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile,line)){
if(line.find('z') != line.npos){
std::cout << line << "\n";
}
}
}
Upvotes: 3
Reputation: 9766
getline
extracts characters from the source and stores them into the variable line
until the delimitation character is found. Your delimiter character is a space (" "
), which isn't present in the file, so line
will contain the whole file.
Try getline(infile, line, '\n')
or simply getline(infile, line)
instead.
Upvotes: 2
Reputation: 28300
The method find
returns the index of the found character, where 0 is a perfectly valid index. If the character is not found, it returns npos
. This is a special value whcih indicates "not found", and it's nonzero to allow 0 to refer to a valid index. So the correct check is:
if (line.find('z') != string::npos)
{
// found
}
Upvotes: 1