M K
M K

Reputation: 317

Counting new lines, tabs, and spaces

I'm working my way through C++ Primer 5th edition to teach myself C++. I came across a problem in the book that I don't know how to solve in Chapter 5 using the tools they have given me thus far. I have previous programming experience and have solved this myself using noskipws. I'm looking for help on how to solve this problem with minimal use of libraries, think the first 4-5 chapters of a beginner book.

The problem is to find and count all the vowels, spaces, tabs, and newline characters as they are read using if statements. My solution to the problem is:

// Exercise 5.9
int main() 
{
char c;
int aCount = 0;
int eCount = 0;
int iCount = 0;
int oCount = 0;
int uCount = 0;
int blankCount = 0;
int newLineCount = 0;
int tabCount = 0;   
while (cin >> noskipws >> c) 
{       
    if( c == 'a' || c == 'A')
        aCount++;
    else if( c == 'e' || c == 'E')
        eCount++;
    else if( c == 'i' || c == 'I')
        iCount++;
    else if( c == 'o' || c == 'O')
        oCount++;
    else if( c == 'u' || c == 'U')
        uCount++;       
    else if(c == ' ')
        blankCount++;       
    else if(c == '\t')
        tabCount++;     
    else if(c == '\n')
        newLineCount++;     
}
cout << "The number of a's: " << aCount << endl;
cout << "The number of e's: " << eCount << endl;
cout << "The number of i's: " << iCount << endl;
cout << "The number of o's: " << oCount << endl;
cout << "The number of u's: " << uCount << endl;
cout << "The number of blanks: " << blankCount << endl;
cout << "The number of tabs: " << tabCount << endl;
cout << "The number of new lines: " << newLineCount << endl;    
return 0;
}

The only other way I can think to solve this is using getline() and then counting the amount of times it loops to get the '/n' count and then step through each string to find the '/t' and ' '.

Thanks for the assistance in advance.

Upvotes: 0

Views: 6571

Answers (2)

Drew Dormann
Drew Dormann

Reputation: 63775

You can avoid noskipws by replacing this

while (cin >> noskipws >> c) 

with

while ( cin.get(c) ) 

The extraction operator >> observes delimiter rules, including whitespace.

istream::get does not, and extracts the data verbatim.

Upvotes: 5

Jamin Grey
Jamin Grey

Reputation: 10487

Your code works perfectly fine:

Input:

This is a test or something
New line
12345
Test 21

Output:

The number of a's: 1
The number of e's: 5
The number of i's: 4
The number of o's: 2
The number of u's: 0
The number of blanks: 7
The number of tabs: 0
The number of new lines: 3

I'd recommend checking out the std::tolower() function, for testing upper and lowercase characters at the same time. Also, to check for any kind of letter, look into the std::isalpha() std::isdigit(), std::isspace(), and similar functions.

Further, you could make the function not dependant on std::cin, and instead use std::cin to get a string, and pass the string into the function, that way the function could be used for any string, not just std::cin input.

To avoid using noskipws (which I personally think is fine), one option is to do this: (as an alternative option to the other solutions already offered)

std::string str;
//Continue grabbing text up until the first '#' is entered.
std::getline(cin, str, '#');
//Pass the string into your own custom function, to keep your function detached from the input.
countCharacters(str); 

(See here for an example)

Upvotes: 0

Related Questions