Reputation: 21
vector<string> wordstocheck;
in.open("readin.txt");
string line;
string word = "";
int linecount = 0;
while (getline(in, line))
{
//cout << line << endl;
for (int i = 0; i < line.size(); i++)
{
if(isalpha(line[i]))
{
word.push_back(tolower(line[i]));
}
else if (line[i] == ' ' || ispunct(line[i]) || line[i] == '\n')
{
wordstocheck.push_back(word);
word = "";
}
}
linecount++;
}
for (int i = 0; i < wordstocheck.size(); i++)
{
cout << wordstocheck[i] << endl;
}
system("pause");
}
The code above reads in the following from a .txt file:
If debugging is the
process of removing bugs.
Then programming must be the
process of putting them in.
I'm trying to get the program to recognize each word, and save that individual word into a vector, and then print that vector of words out. It does pretty well with the exception of the two 'the's on the first and third lines.
Output:
if
debugging
is
theprocess
of
removing
bugs
then
programming
must
be
theprocess
of
putting
them
in
Press any key to continue . . .
It doesn't split up "theprocess" as I had hoped.
Upvotes: 2
Views: 2559
Reputation: 320
So far i know, getline reads a whole line and does not recognize a carriage return. The only way i know is to read the file, by read it char by char. Here is a example that gives the correct result:
#include <iostream> // std::cin, std::cout
#include <fstream> // std::ifstream
int main ()
{
char str[256];
int line = 1;
int charcount = 0;
std::cout << "Enter the name of an existing text file: ";
std::cin.get (str,256);
std::ifstream is(str);
if (!is)
{
std::cerr << "Error opening file!" << std::endl;
return -1;
}
char c;
while ((c = is.get()) && is.good()) // loop while extraction from file if possible
{
if (c == 10 || c == 13 || c == 32) // if it is a line break or carriage return or space
{
std::cout << std::endl;
line++;
}
else // everything else
{
std::cout << c;
charcount++;
}
}
is.close();
std::cout << std::endl; // close file
std::cout << line << " lines" << std::endl;
std::cout << charcount << " chars" << std::endl;
return 0;
}
Upvotes: 1
Reputation: 490158
If you want to read a word at a time, why use std::getline
in the first place?
// read the words into a vector of strings:
std::vector<std::string> words{std::istream_iterator<std::string(in),
std::istream_iterator<std::string()};
You can use std::for_each
or std::transform
to convert everything to lower case, and finally print them out with for (auto const &w : words) std::cout << w << "\n";
Upvotes: 1
Reputation: 129374
getline
won't read the newline. However, in this case it's relatively simple to work around this problem.
Where you currently have linecount++;
, add these lines before it:
if (word != "")
{
wordstocheck.push_back(word);
word = "";
}
You may want to use the same if (word != "")
on the first place where you push the word
onto wordstocheck
since if the text has "A Word", you'd add the word "A" followed by an empty word for as the seconds space triggers the word to be added to the list.
As an alternative, you could get rid of getline, and just use int ch = in.get()
to read a character at a time from the input. Then instead of counting lines inside the while()...
, and use ch
instead of line[i]
al through the loop, and then add a second if inside the else if
section, which checks for newline and counts up linecount. This would probably make for shorter code.
Upvotes: 4
Reputation: 1143
I believe the problem is that you're expecting the newline character to be included in the result from getline()
, which it isn't. It seems like if you take the two lines you already have in that block:
wordstocheck.push_back(word);
word = "";
And add them alongside the line:
linecount++;
Then it should work as you expect.
Upvotes: 2