user2533614
user2533614

Reputation: 21

How can I check a string to see if a carriage return exists in C++?

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

Answers (4)

Dippo
Dippo

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

Jerry Coffin
Jerry Coffin

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

Mats Petersson
Mats Petersson

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

Ben S.
Ben S.

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

Related Questions