【问题标题】:C++ While loop scoping issueC ++ While循环范围问题
【发布时间】:2021-03-05 00:28:09
【问题描述】:

我最近开始学习 C++,目前正在尝试构建一个我最近在 python 中构建的工具。我的问题是我不知道如何使单词列表的长度成为全局的,例如:

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char* argv[]) {
    ....
        fstream file;
        file.open(argv[i], ios::in);
        if (file.is_open()) {
            string tp;
            while (getline(file, tp)) {
                // cout << tp << "\n" << endl;
                string words[] = {tp};
                int word_count = sizeof(words) / sizeof(words[0]);
                for (int e = 0; e < word_count; e++) {
                    cout << word_count[e];
                }
            }
            file.close();
            } else {
                cout << "E: File / Directory " << argv[i] << " Does not exist";
                return 0;
            }
    ....
}

在上面写着int word_count = sizeof(words) / sizeof(words[0]);tring words[] = {tp}; 的地方,我希望能够在全局范围内使用它,以便以后可以使用数组的长度和数组本身,以便循环遍历它并使用他们在另一个声明中。

谁能告诉我该怎么做? 顺便说一句,我只做了大约 4 天的 C++,所以如果我不明白你告诉我的内容,请不要生气。

【问题讨论】:

  • 您使用数组而不是 C++ vector 字符串是否有原因?它们会为您调整大小,因此您不必指定数组的大小。
  • 谢谢,刚刚想通了,但我也希望能够在稍后使用 for 循环通过向量从内部获取每个项目,但这都是在另一个语句中继续,所以我需要以某种方式返回向量。关于我如何做到这一点的任何想法? :? |
  • 你可以声明一个向量std::vector&lt;std::string&gt; v;,用v.push_back(some_string)添加它,然后像数组一样在你的for循环中索​​引它:v[index]This page 应该有你需要的所有例子。
  • 数组是二等公民。他们仍然遵循 1970 年代的所有旧 C 规则。它们不生长。它们很难复制,而且它们通常不如遵循现代习语的库容器,就像你习惯从 Python 中引入的那样。 string words[] = {tp}; 是一个字符串数组。永远永远。因为它是在循环内限定的,所以在循环的每次迭代中都会创建一个新的。对你基本没用。如上所述,您需要一个 vector,并且应该在包含您希望使用它的所有位置的最窄范围内定义它。
  • 旁注:如果您的编译器相对较新,您可以将 int word_count = sizeof(words) / sizeof(words[0]); 替换为 int word_count = std::size(words);

标签: c++ loops while-loop scope


【解决方案1】:

string words[] = {tp}; 创建一个数组,其中包含一个元素,即整行。名称words 表示您希望存储单个单词。如果您想在循环完成后使用它,范围也是错误的。您需要在循环之前声明它。使用std::vector&lt;std::string&gt; 来存储单词。它可能看起来像这样:

#include <vector>

int main(int argc, char* argv[]) {
    std::vector<std::string> words;

    // ...
    if (file) {

        std::string word;

        while (file >> word) {     // read one word
            words.push_back(word); // store it in the vector<string>
        }

        std::cout << "word count: " << words.size() << '\n';

        // print all the words in the vector:
        for(std::string& word : words) {
            std::cout << word << '\n';
        }

        // file.close() // not needed, it'll close automatically when it goes out of scope
    }

【讨论】:

  • 这对我有用,我很高兴,但你能否在另一个声明中解释我如何将它与 words.size() 一起使用:pastebin.com/RbgC5isW
  • @bobross 你可以像数组一样使用vector&lt;string&gt;,如果你想words[0]将是第一个单词。 words[1] 将是第二个单词等。您还可以调用接受 std::vector&lt;std::string&gt;&amp; 的函数,以便在程序的其他部分有效地使用它。如果您想在更大的范围内使用它(就像您的 pastebin 建议的那样),您需要在更大的范围之外声明向量。如果我正确阅读了 pastebin 代码,我认为你应该把它放在 main 函数的开头。
  • 对不起,我真的是 C++ 新手,你的意思是我可以在函数中使用 std::vector<:string>&,因为真的,我想成为能够在可调用参数的另一部分使用它
  • @bobross 我在上面更新了我的评论。我也更新了答案并将words 声明移至main 的开头。
  • 感谢您的帮助,现在可以正常使用了。?
【解决方案2】:

这里有很多问题。首先,不是在循环的每次迭代中将tp 添加到名为words 的数组中,而是实际上创建了一个新数组words 并将tp 分配给数组的第一个元素。 words 在 while 循环的每次迭代结束时被销毁,但即使不是,{tp} 表达式也会覆盖数组中已经存在的任何内容。因此,您计算长度的行将始终将长度计算为 1。

接下来,word_count[e] 试图读取名为word_count 的数组的元素e,但word_count 实际上是一个整数。如果这真的编译了,我会感到惊讶。

首先我建议您使用std::vector,然后如果您只是将其范围扩大到循环之外,那么您可以在其他地方使用它。例如:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int main(int argc, char* argv[]) {
        fstream file;
        file.open(argv[i], ios::in);
        std::vector<std::string> words;
        if (file.is_open()) {
            string tp;
            while (getline(file, tp)) {
                words.push_back(tp); // Add tp to the vector of words
            }
            int word_count = words.size(); // vectors 'know' their own size.
            for (int e = 0; e < word_count; e++) {
                    cout << words[e];
            }
            file.close();
            } else {
                cout << "E: File / Directory " << argv[i] << " Does not exist";
                return 0;
            }
        }
        // You can now use words as you please, because it is still in scope.
}

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 2011-10-21
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多