【问题标题】:Code reading extra line in my loop?在我的循环中读取额外行的代码?
【发布时间】:2016-05-30 02:43:59
【问题描述】:

我的目标是从输入文件中读取并计算至少有 1 个小写字母和 1 个数字的行数。我已经解决了我剩下的代码,它计算了所有的小写字母、大写字母、数字、字符和单词都没有问题。我还从输入文件中读取并逐字反转行。我似乎无法弄清楚为什么当只有 7 个带有 1 个小写字母和 1 个数字的代码时,为什么要计算 8 行代码。在对所有其他循环使用 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 和顶部,并且还声明了我的 sstream 变量。我的库包括 &lt;sstream&gt; &lt;fstream&gt; &lt;string&gt; &lt;iostream&gt;&lt;algorithm&gt;(用于早期部分。

我得到的输出是

8

什么时候应该是 7。最后一行不应该被计算在内,因为它没有小写字母和数字。我在想第一行被第二次阅读然后停止。我正在学习 C++ 课程,但尚未学习如何使用调试器。提前谢谢你。

【问题讨论】:

  • 在循环的开始,在你读完这行之后,打印出digitlowerCase:你会发现它们没有被重置为0,所以基本上它们总是&gt;=1,即使行上没有数字。
  • 啊,我明白了。这是完全有道理的。我需要重置循环中的值。那工作得很好。非常感谢。我真的绞尽脑汁。

标签: c++ loops getline stringstream counting


【解决方案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;

更好的是,您可能只需在 read line 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++;
    }

}   

【讨论】:

  • 非常感谢您的回复!我非常感谢您花时间解释这一点。通过在 while 循环下的 read 中添加 lowerCase = 0 和 digits = 0,它就像一个魅力。我没有想到这是问题所在。我将继续检查我的台词以仔细检查正在发生的事情。希望我能给你的不仅仅是赞成票和支票!
【解决方案2】:

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

我会将cout &lt;&lt; line &lt;&lt; endl; 添加到您的第一个while 循环中。这样你就可以输出这些行是如何被读取的以及是否有重复的。还要检查您的 islower(char)isdigit(char) 函数,以确保它们正在读取适当的 ascii 范围。

【讨论】:

    猜你喜欢
    • 2014-03-14
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多