2014-01-26 183 views
1

我有一個使用for循環打印出字符串字符的程序。它還必須反向打印相同的字符,這是我遇到問題的地方。有人可以幫我弄清楚爲什麼第二個for循環沒有執行?C++使用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; 
} 
+0

您不應該使用int來存儲字符串的長度,該字符串的長度可能會超出整數範圍。 – PrinceGautham

回答

5

您需要將i初始分配給長度減一或數組中的最後一個索引值。

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

附錄:這是運行時錯誤消息「在拋出'std :: out_of_range'的實例後終止調用」,或者類似的,你應該得到的,試圖告訴你。 – zwol

+0

就是這樣,非常感謝! – Bobby

+0

@Bobby如果你發現這個答案有幫助,你應該考慮[接受答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。 –

-1
for(myAnimal.length(); i > -1; i--){ 
    ^

這並不做任何事情。你獲取的價值,然後把它扔掉。

您的意思是i = myAnimal.length() - 1

+0

對不起,做了一個快速編輯。應該是我= myAnimal.length()。 – Bobby

1

由於字符的位置從0開始的myAnimal的最後一個字符在(myAnimal.length()-1)位置不myAnimal.length()所以你要那裏開始第二循環。

-3

代替

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,長度在可接受的範圍() - 1]

而不是int類型,最好使用std :: string爲std :: string :: size_type成員函數長度的返回類型提供的類型。

+1

您至少應該*嘗試*解釋爲什麼您的更改有幫助。此外,將循環增量移動到「cout」操作中很聰明,但通常被認爲是不好的風格。 – zwol

+1

我覺得這段代碼對於初學者來說比較混亂。 –

0

@Lokno已經爲您提供了正確的答案。但是,讓我多挑一點你的代碼,向你展示一些其他的選擇,並糾正一些小錯誤。

首先,你實際上並沒有發佈編譯的例子,因爲你忘了展示包括頭<iostream><string>,也沒有表現出using namespace std;那是在你的代碼暗示。

其次,對於常規for循環,除非實際需要將其用作返回值,否則寧願將循環變量保留在循環內部。還有prefer pre-increment++i超過後增加i++。此外,由於您確定了正確的循環索引,因此沒有理由在未檢查的[]版本上使用邊界檢查元素訪問at()

在C++ 11中,您有range-for循環,它允許使用更短和更傻的代碼,其中我還使用了auto,您可以在其中使用char。不幸的是,沒有反向範圍循環。如果您使用i >= 0而不是i > -1,則正確的基於索引的反向循環可能更易於閱讀。

然後是使用std::copy在您使用的std::string迭代器接口(尤其是在反向迭代rbegin()rend())通過綁定到標準輸出一個ostream_iterator每個字符複製算法基於循環。

順便說一下,我用分隔符"|"而不是換行符來看東西更容易,適應你的口味。在任何情況下,使用std::endl可以有​​,因爲它每次刷新輸出緩衝區。

#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

0

你可以使用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」(而不是遞減的話),因爲這是一個反向迭代。