【问题标题】:C++ Unwanted infinite while loopC ++不需要的无限while循环
【发布时间】:2010-02-20 19:37:18
【问题描述】:

当我在 C++ 中使用以下代码时,我得到一个无限循环,我不明白为什么。我怀疑问题出在input_words() 函数中。代码如下:

#include<iostream>
using namespace std;

string input_words(int maxWords) {
    int nWord = 0;
    string words[maxWords];
    string aWord = "";
    while (aWord != "Quit" && nWord < maxWords) {
        cout << "Enter a number ('Quit' to stop): ";
        getline (cin, aWord);
        words[nWord] = aWord;
        nWord++;
    }
    return *words;
}

int num_words (string words[], int maxWords) {
    int numWords = 0;
    for (int i=0; i<maxWords; i++) {
        if (words[i] == "Quit") {
            break;
        }
        numWords++;
    }
    return numWords;
}

int main() {

    const int MAX_WORDS = 100;
    string words[MAX_WORDS] = input_words(MAX_WORDS);

    int lenWords = num_words(words, MAX_WORDS);
    cout << "\nThere are " << lenWords << " words:\n";

    for (int i=0; i<MAX_WORDS; i++) {
        if (words[i] == "Quit") {
            break;
        }
        cout << words[i] << "\n";
    }
    return 0;
}

更具体地说,即使在提示输入单词时键入“退出”,我也无法退出。我怎么能解决这个问题?我知道这是菜鸟代码 :) 我刚刚开始使用 C++

【问题讨论】:

  • 这应该可以正常工作。此外,这是一个扩展,而不是 C++:string words[maxWords]; 在 C++ 中,数组具有恒定大小。如果你想要一个动态数组,你应该使用std::vector&lt;std::string&gt;,并使用push_back 添加东西。这也消除了您对最大尺寸的需求。最后,这个:return *words; 将只返回第一个字符串。也许您的意图是返回整个数组,在这种情况下,将返回类型设为 std::vector&lt;std::string&gt; 并返回向量。
  • @GMan:afaik g++ 支持堆栈上动态大小的数组,但请注意这不符合标准。
  • 非常感谢 GMan!我觉得你应该发布(或发布)这个作为答案。在阅读您的评论之前,我刚刚发布了一个关于声明向量的新问题。我还认为向量是要走的路,但我没有成功声明它。
  • @JP:因此 GMan 将其称为扩展,即标准未定义的附加功能。
  • @JPvdMerwe:这个 g++ 问题将如何影响特定问题?

标签: c++ function user-input infinite-loop


【解决方案1】:

我是这样修改函数的:

string input_words(int maxWords) {
    cout << "started" << endl;
    int nWord = 0;
    string words[maxWords];
    string aWord = "";
    while (aWord != "Quit" && nWord < maxWords) {
        cout << "Enter a number ('Quit' to stop): ";
        getline (cin, aWord);
        words[nWord] = aWord;
        nWord++;
    }
    cout << "finished" << endl;
    return *words;
}

输入退出后,打印“完成”,然后再次“开始”。 您的代码多次调用该函数。

问题是函数只返回一个字符串。所以这条线

string words[MAX_WORDS] = input_words(MAX_WORDS);

似乎调用了函数 input_words MAX_WORDS 次。

一个好方法是切换到vector&lt;string&gt;

vector<string> input_words(int maxWords) {
    vector<string> words;
    string aWord;
    while (aWord != "Quit" && nWord < maxWords) {
        cout << "Enter a number ('Quit' to stop): ";
        getline (cin, aWord);
        words.push_back(aWord);
    }
    return words;
}

...
vector<string> words = input_words(MAX_WORDS);

【讨论】:

  • 它调用 input_words() MAX_WORDS 次很好。
  • @Vlad 确实,你甚至在我输入整个代码之前就提出了建议,包括单词 [MAX_WORDS] 位:) 非常感谢矢量实现,这正是我要去的地方,但我发现初学者很难获得有关 C++ 方法退出的信息。 (我来自 Python,其中 help() 随时可以使用)。有什么推荐的最喜欢的网站在哪里可以找到这种东西吗?我刚刚遇到cppreference.com/wiki,但如果有更好或替代的,我都愿意!
  • @Morlock:为了快速入门,我在几年前使用过icce.rug.nl/documents/cplusplusstackoverflow.com其实也很好! :-)
  • @Vlad:我相信 stackoverflow.com 很棒。到目前为止,没有它,我将无法学习 C++!谢谢你的链接,我会用的。您用于日常帮助的任何其他来源?
  • @Morlock:我经常使用sgi.com/tech/stl/table_of_contents.html;但是它更多的是参考而不是教程。
【解决方案2】:

我尝试了以下测试程序,它可以工作:

{0,506}$> cat testcin.cpp && make testcin && ./testcin.exe
#include <iostream>
using namespace std;

int main()
{
    const int maxWords = 5;
    int nWord = 0;
    string words[maxWords];
    string aWord = "";
    while (aWord != "Quit" && nWord < maxWords) {
        cout << "Enter a number ('Quit' to stop): ";
        getline (cin, aWord);
        words[nWord] = aWord;
        nWord++;
    }    
}

make: `testcin' is up to date.
Enter a number ('Quit' to stop): test
Enter a number ('Quit' to stop): Quit

[Vlad@rabbit] [20:53:53] [~/c++]
{0,507}$> 

【讨论】:

    【解决方案3】:

    我认为问题出在你的主要位置,你返回input_words() 的结果,这是一个string 来初始化main() 中的words,它的类型是string[]。肯定是这个问题。

    重写为使用vector

    #include<iostream>
    #include<vector>
    #include<string>
    using namespace std;
    
    vector<string> input_words(int maxWords) {
        int nWord = 0;
        vector<string> words;
        string aWord = "";
        while (aWord != "Quit" && nWord < maxWords) {
            cout << "Enter a number ('Quit' to stop): ";
            getline (cin, aWord);
            words.push_back(aWord);
            nWord++;
        }
        return words;
    }
    
    int num_words (vector<string> words) {
        // return words.size();
    
        int numWords = 0;
        vector<string>::iterator it = words.begin();
        for (; it != words.end(); it++) {
            if (*it == "Quit") {
                break;
            }
            numWords++;
        }
        return numWords;
    }
    
    int main() {
    
        const int MAX_WORDS = 100;
        vector<string> words = input_words(MAX_WORDS);
    
        int lenWords = num_words(words);
        cout << "\nThere are " << lenWords << " words:\n";
    
        vector<string>::iterator it = words.begin();
        for (; it != words.end(); it++) {
            if (*it == "Quit") {
                break;
            }
            cout << *it << endl;
        }
        return 0;
    }
    

    忘记以下内容,C++ getline() 会自动剥离 '\n'。

    您是否检查过您的getline() 单词末尾是否有换行符? 也就是说,

    "Quit" != "Quit\n".
    

    【讨论】:

    • 我在 while 循环中有一个有效的实现,效果很好(有点像弗拉德的回答)。然后我试图用它制作一个函数并陷入无限循环。我正在编辑问题以添加完整的代码,而不仅仅是函数。
    • Documentation 说:如果找到分隔符,则将其提取并丢弃,即不存储,然后开始下一个输入操作。
    • @Vlad:是的,我看错了 C getline。
    猜你喜欢
    • 2016-08-27
    • 2015-04-29
    • 1970-01-01
    • 2013-02-22
    • 2016-04-21
    • 2021-10-15
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多