【问题标题】:c++ strings line reversion to the consolec++字符串行恢复到控制台
【发布时间】:2020-05-09 15:16:08
【问题描述】:

我只想知道这段 C++ 代码有什么问题: 我必须从控制台获取字符并计算写了多少行。然后我必须以相反的顺序显示它们。即:如果我写 3 行:“hi”、“im”、“lucas”,每行都以 '\n' 结尾。我必须把它们颠倒过来,所以它会一行一行地写“lucas”、“im”、“hi”。 首先,我将这些行“保存”在“字符串”向量中,然后用一个从结尾到开头的迭代器显示它们。 我将 VSCode 与 g++ 一起使用,最终迭代器向量循环似乎存在问题。程序停在那里并抛出一个 SIGINT 中断。 为什么会这样?如何纠正?

#include <iostream>
#include <vector>
using namespace std;
int  main()
{
    string strLines = "";
    int c;
    do {
        c = getc(stdin);
        strLines += c;
    } while (c != EOF);
    size_t oldIndex = 0;
    size_t newIndex;
    int totalStrings = 0;
    vector<string> strVector;
    while (1)
    {
        newIndex = strLines.find('\n', oldIndex);
        if (newIndex == string::npos)
            break;
        string strToPush = strLines.substr(oldIndex, newIndex+1);
        strVector.push_back(strToPush + '\0');
        oldIndex = newIndex+1;
        totalStrings++;
    } 
    //reverse string
    for (vector<string>::iterator it = strVector.end()-1 ; it != strVector.begin(); it--)
    {
        string strShow = *it;
        cout << *it;
    }
    c = getchar();
    return EXIT_SUCCESS;    
}

【问题讨论】:

  • 一个堆栈会更好。
  • 你甚至没有向后迭代。为什么有一个 totalStrings 变量?你从不使用它,向量知道它们有多大。

标签: c++ vector iterator console


【解决方案1】:

您所展示的内容有很多问题。不必要的变量,没有实际的向后迭代,错误的循环条件等。

这是带有向量的代码:

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

int main() {
  std::string line;
  std::vector<std::string> entries;

  do {
    std::cout << "Enter a thing: ";
    std::getline(std::cin, line);

    if (!line.empty()) {
      entries.push_back(line);
    } else {
      break;
    }
  } while (!line.empty());

  for (auto it = entries.rbegin(); it != entries.rend(); ++it) {
    std::cout << *it << ' ';
  }
  std::cout << '\n';
}

如果你想倒退,你可以使用反向迭代器。就这么简单。但是向量并不是理想的数据结构。堆栈非常适合。

#include <iostream>
#include <stack>
#include <string>

int main() {
  std::string line;
  std::stack<std::string> entries;

  do {
    std::cout << "Enter a thing: ";
    std::getline(std::cin, line);

    if (!line.empty()) {
      entries.push(line);
    } else {
      break;
    }
  } while (!line.empty());

  while (!entries.empty()) {
    std::cout << entries.top() << ' ';
    entries.pop();
  }
  std::cout << '\n';
}

这两段代码都能以更直接的方式为您提供所需的内容。当您只按 Enter 而不输入任何其他内容(空字符串)时,它们会终止用户输入循环。在利用标准库(向量、堆栈、字符串等)时,请务必花时间熟悉它们的功能。可能会为您处理常见任务。

【讨论】:

    【解决方案2】:
    1. 不需要空终止符是std::string
    2. 永远不要将最后一个字符串添加到向量中,如果遇到结束行字符 (\n) 就会中断,并且不要将最后一个字符串添加到向量中。您可以通过在循环后添加strVector.push_back(strLines.substr(oldIndex)) 来解决它
    3. 正如 @sweenish 在 cmets 中提到的,stack 会更好
    4. 您制作了很多副本。使用 std::move 或就地副本。
    5. 你还是错过了第一个元素,使用rbegin()rend()
    6. (运行时发现)你应该使用substr(oldIndex, newIndex-oldIndex)
    #include <iostream>
    #include <vector>
    using namespace std;
    int  main()
    {
        string strLines = "this\nis\nan\nexample\nfor\nsplitting";
        size_t oldIndex = 0;
        size_t newIndex;
        vector<string> strVector;
        while (1)
        {
            newIndex = strLines.find('\n', oldIndex);
            if (newIndex == string::npos) {
                break;
            }
            strVector.push_back(strLines.substr(oldIndex, newIndex-oldIndex));
            oldIndex = newIndex+1;
        } 
        strVector.push_back(strLines.substr(oldIndex));
        //reverse string
        for (auto it = strVector.rbegin() ; it != strVector.rend(); ++it)
        {
            cout << *it << "\n";
        }
        return EXIT_SUCCESS;    
    }
    

    【讨论】:

    • 是的,这是您向我展示的正确方法。正如你所说,堆栈比向量好得多。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 2013-02-10
    • 2017-08-17
    • 1970-01-01
    相关资源
    最近更新 更多