代码在循环中读取额外的行?

时间:2016-02-18 04:32:37

标签: c++ loops getline stringstream counting

我的目标是从输入文件中读取并计算至少包含1个小写字母和1个数字的行数。我已经解决了我的其余代码,它计算了所有的小写,大写,数字,字符和单词没有问题。我也从输入文件中读取并逐字反转。我似乎无法弄清楚为什么代码计算8行时只有7个1小写和1个数字。在所有其他循环中使用getline()时,我没有遇到任何问题。我不是专门为某人为我编写代码。我想解释为什么会发生这种情况?

我的输入文件包含:

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

本节的代码是:

    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;
 }

我已将所有的int变量初始化为0和top,并且我也声明了我的sstream变量。我的图书馆包括<sstream> <fstream> <string> <iostream><algorithm>(用于之前的部分。

我得到的输出是

8

当它应该是7.最后一行不应该被计算,因为它没有小写字母和没有数字。我想第一行是第二次读,然后停止。我正在介绍C ++类,还没有学习如何使用调试器。提前谢谢。

2 个答案:

答案 0 :(得分:1)

您明确表示将所有int个变量初始化为0,这很好;但是,让我们看看你的代码(格式化,以便缩进更有意义):

// 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++;
    }

}

在这里,您读取一行,并浏览该行上的所有字符,如果您找到小写字符或数字,则增加一个变量。阅读下一行后会发生什么?您尚未将这些变量重置为0,因此在阅读下一行时,它们都已经高于1

您需要以下内容:

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;

更好的是,您可以在读取行 while循环中声明这些变量:

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

虽然您还没有被教过使用调试器,但是调试的一种很好的方法是使用cout语句。放入一些打印语句以确定在任何给定时间所有变量是什么:

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++;
    }

}   

答案 1 :(得分:0)

自从我用C ++编写代码以来已经有一段时间了。除了调试程序之外,还有其他调试方法。

我会在您的第一个while循环中添加cout << line << endl;。这样,您可以输出如何读取行以及是否重复行。同时检查您的islower(char)isdigit(char)函数,确保它们的读取范围是适当的。