-1

My goal is to read from an input file and count the number of lines that have at least 1 lowercase letter and 1 digit. I have already solved the rest of my code which counted all of the lowercase, uppercase, digits, characters and words no problem. I have also read from the input file and reversed the lines word by word. I cannot seem to figure out why the code is counting 8 lines when there are only 7 with 1 lowercase and 1 digit. While using getline() for all of the other loops, I've had no issues. I'm not looking specifically for someone to write the code for me. I'd just like an explanation of why this is happening if possible?

My input file contains:

This is a test file for hw3 
How many Uppercase letters are in this f1le?
How many Lowercase letters are in this F1le?
H0W mAnY dIg1ts ar3 1N in this FILe?
Turn the 1npU7 N4m3 int0 its reverse
reverse the Lines to their opp05173 coutnerpart
find tOTal NumbEr of characTer5 in F1le
THIS IS A TEST LINE

My code for this section is:

    inFile.clear();
    inFile.seekg(0, inFile.beg);

    while(getline(inFile, line)){
        wordInput.str(line);
        wordInput.clear();
        wordInput.seekg(0);

    while(wordInput.get(c)){
        if(islower(c)){
            lowerCase++;
        }   
        else if(isdigit(c)){
            digit++;
        }   
     }   

        if(lowerCase >= 1 && digit >= 1){ 
            lineCount++;
        }

     }    

    cout << lineCount << endl;

    return 0;
 }

I have initialized all of my int variables to 0 and the top and I have declared my sstream variables as well. My libraries include <sstream> <fstream> <string> <iostream> and <algorithm> (which was used for earlier parts.

The output I am getting is

8

when it should be 7. The final line should not be counted as it has no lowercase letters and no digits. I am thinking that the first line is being read a second time and then stopping. I am in an intro to C++ class and have yet to learn how to use the debugger. Thank you in advance.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
ryanpback
  • 275
  • 4
  • 17
  • 3
    At the start of the loop, right after you've read the line, print out `digit` and `lowerCase`: you will find they are not being reset to `0`, so essentially they are always `>=1` even when there are no digits on the line. – Tas Feb 18 '16 at 04:38
  • Ah, I see. That makes complete sense. I needed to reset the value in the loop. That worked perfectly. Thank you very much. I was really racking my brain. – ryanpback Feb 18 '16 at 04:47

2 Answers2

1

You made it clear that that you initialise all int variables to 0, which is great; however, let's have a look at your code (formatted so the indentation makes more sense):

// read line from file
while(getline(inFile, line))
{
    wordInput.str(line);
    wordInput.clear();
    wordInput.seekg(0);

    // read character
    while(wordInput.get(c))
    {
        if(islower(c))
        {
            lowerCase++;
        }   
        else if(isdigit(c))
        {
            digit++;
        }   
    }   

    if(lowerCase >= 1 && digit >= 1){ 
        lineCount++;
    }

}

Here you read a line, and go through all characters on that line, and if you find a lowercase character, or a digit, you increment a variable. What happens when you read the next line? You haven't reset those variables back to 0, so upon reading the next line they would both be above 1 already.

You need the following:

while(getline(inFile, line))
{
    wordInput.str(line);
    wordInput.clear();
    wordInput.seekg(0);

    // We're about to start reading this line, so obviously we haven't found any yet
    digit = 0;
    lowerCase = 0;

Better yet, you can probably just declare those variables within the read line while loop:

while(getline(inFile, line))
{
    int digit = 0;
    int lowerCase = 0;

Although you haven't been taught to use a debugger, a great way of debugging is with cout statements. Put some print statements in to determine what all your variables are at any given time:

while(getline(inFile, line))
{
    std::cout << "read line " << line << std::endl;
    while(wordInput.get(c))
    {
        std::cout << "lowercase found so far: " << lowerCase << std::endl;
        std::cout << "digits found so far: " << digit << std::endl;
        if(islower(c))
        {
            std::cout << "lowercase character found: " << c << std::endl;
            lowerCase++;
        }   
        else if(isdigit(c))
        {
            std::cout << "digit found: " << c << std::endl;
            digit++;
        }   
    }   

    if(lowerCase >= 1 && digit >= 1)
    { 
        std::cout << "found a lowercase character (" << lowerCase << ") or a digit (" << digit << ")" << std::endl;
        lineCount++;
    }

}   
Tas
  • 7,023
  • 3
  • 36
  • 51
  • Thank you very much for the response! I really appreciate the time you took to explain this. By adding the lowerCase = 0 and digits = 0 in the read under the while loop it works like a charm. I had not thought of that being the problem. I will continue to cout my lines to double check what is happening. Wish I could give you more than just an up vote and a check! – ryanpback Feb 18 '16 at 05:05
0

It's been awhile since I have coded in C++. There are other ways to debug than a debugger program.

I would add cout << line << endl; to your first while loop. That way you can output how the lines are being read and if any are being repeated. Also check your islower(char) and isdigit(char) functions to make sure they are reading appropriate ascii ranges.

Chace
  • 46
  • 5