【问题标题】:C++ Printing a string in reverse using a for loopC ++使用for循环反向打印字符串
【发布时间】:2014-02-17 16:49:44
【问题描述】:

我有一个使用 for 循环打印出字符串字符的程序。它还必须反向打印相同的字符,这就是我遇到问题的地方。有人能帮我弄清楚为什么第二个 for 循环没有执行吗?

int main()
{
    string myAnimal;

    cout << "Please enter the name of your favorite animal.\n";
    cin >> myAnimal;

    // This loop works fine
    int i;
    for(i = 0; i < myAnimal.length(); i++){
        cout << myAnimal.at(i) << endl;
    }

    // This one isn't executing
    for(i = myAnimal.length(); i > -1; i--){
        cout << myAnimal.at(i) << endl;
    }
    return 0;
}

【问题讨论】:

  • 你不应该使用int来存储字符串的长度,字符串的长度可能会超出整数范围。

标签: c++ string for-loop reverse


【解决方案1】:
for(myAnimal.length(); i > -1; i--){
    ^

这没有任何作用。您获取该值,然后将其丢弃。

您是说i = myAnimal.length() - 1 吗?

【讨论】:

  • 抱歉,做了一个快速编辑。应该是 i = myAnimal.length()。
【解决方案2】:

您首先需要将 i 分配给长度减一,或数组中的最后一个索引值。

for(i = myAnimal.length()-1; i >= 0; i--){
    cout << myAnimal.at(i) << endl;
}

【讨论】:

  • 附录:这是运行时错误消息“在抛出 'std::out_of_range' 实例后调用终止”或类似的,你应该得到的,试图告诉你。跨度>
  • @Bobby 如果你觉得这个答案有帮助,你应该考虑accepting the answer
【解决方案3】:

因为字符位置从 0 开始,myAnimal 的最后一个字符在位置 (myAnimal.length()-1) 而不是 myAnimal.length() 所以你想在那里开始第二个循环。

【讨论】:

    【解决方案4】:

    而不是

    int i;
    for(i = 0; i < myAnimal.length(); i++){
        cout << myAnimal.at(i) << endl;
    }
    
    // This one isn't executing
    for(i = myAnimal.length(); i > -1; i--){
        cout << myAnimal.at(i) << endl;
    }
    

    for ( string::size_type i = 0; i < myAnimal.length(); i++ ){
        cout << myAnimal.at(i) << endl;
    }
    
    // This one isn't executing
    for ( string::size_type i = myAnimal.length(); i != 0; ){
        cout << myAnimal.at( --i) << endl;
    }
    

    在您的代码中,您尝试访问超出可接受范围的字符串元素,该范围等于 [0, length() - 1]

    此外,最好使用 std::string 为成员函数长度的返回类型 std::string::size_type 提供的类型,而不是 int 类型。

    【讨论】:

    • 您至少应该尝试解释为什么您的更改会有所帮助。此外,将循环增量移动到 cout 操作中很聪明,但通常被认为是不好的风格。
    【解决方案5】:

    @Lokno 已经为您提供了正确答案。但是,让我对您的代码进行更多的挑剔,以向您展示一些其他替代方案并纠正一些小错误。

    首先,您实际上并没有发布编译示例,因为您忘记显示包含的标头&lt;iostream&gt;&lt;string&gt;,也没有显示代码中隐含的using namespace std;

    其次,对于常规的for 循环,最好将循环变量保留在循环内,除非您确实需要将其用作返回值。还有prefer pre-increment++i 超过后增量i++。此外,由于您已确定正确的循环索引,因此没有理由在未检查的 [] 版本上使用边界检查元素访问 at()

    在 C++11 中,你有 range-for 循环,它允许更短和更简单的代码,我还使用了 auto,你可以使用 char。不幸的是,没有反向 range-for 循环。如果您使用i &gt;= 0 而不是i &gt; -1,正确的基于索引的反向for 循环可能更易于阅读。

    然后有一个使用std::copy 的基于算法的循环,您可以使用std::string 的迭代器接口(特别是反向迭代器rbegin()rend())通过绑定的ostream_iterator 复制每个字符到标准输出。

    顺便说一句,我使用分隔符 "|" 而不是换行符,以便更轻松地查看内容,适应您的口味。无论如何,使用std::endl 可以有performance implications,因为它每次都会刷新输出缓冲区。

    #include <algorithm>
    #include <iterator>
    #include <iostream> // you forgot this
    #include <string>   // you forgot this
    
    int main()
    {
        using namespace std;    // you forgot this
    
        // let's pretend this is the string
        string myAnimal = "Please enter the name of your favorite animal.";
    
        // keep the loop variable local, prefer pre-increment
        for (int i = 0; i < myAnimal.length(); ++i)
            cout << myAnimal[i] << "|";    // prefer [] over at()
        std::cout << "\n";
    
        // C++11 range-for
        for (auto c : myAnimal)
            std::cout << c << "|";
        std::cout << "\n";
    
        // index-based reverse loop
        for (int i = myAnimal.length() - 1; i >= 0; --i)
            cout << myAnimal[i] << "|";
        std::cout << "\n";
    
        // algorithm-based reverse loop
        std::copy(myAnimal.rbegin(), myAnimal.rend(), ostream_iterator<char>(cout, "|"));
        std::cout << "\n";
    
        // main implicitly return 0
    }
    

    Live Example。 PS:main() 成功后隐式返回0

    【讨论】:

      【解决方案6】:

      你可以使用reverse iterators

      #include <iostream>
      #include <string>
      
      int main() {
        std::string myAnimal;
      
        std::cout << "Please enter the name of your favorite animal.\n";
        std::cin >> myAnimal;
      
        // Iterate in reverse order
        for(auto c = myAnimal.rbegin(); c != myAnimal.rend(); ++c) {
          std::cout << *c << std::endl;
        }
      }
      

      请注意,您必须递增变量“c”(而不是递减它),因为这是一个反向迭代器。

      【讨论】:

        猜你喜欢
        • 2020-05-22
        • 1970-01-01
        • 2017-04-13
        • 1970-01-01
        • 2021-02-25
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        相关资源
        最近更新 更多