I have a program that prints out the characters of a string using a for-loop. It must also print the same characters in reverse, which is where I\'m having problems. Can someone
You need to assign i initially to the length minus one, or the last index value in the array.
for(i = myAnimal.length()-1; i >= 0; i--){
cout << myAnimal.at(i) << endl;
}
Instead of
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;
}
write
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;
}
In your code you try to access an element of the string that is beyond the acceptable range that is equal to [0, length() - 1]
Also instead of type int it is better to use the type that std::string provides for the return type of member function length that is std::string::size_type.
@Lokno already provided you with the correct answer. However, let me nitpick your code a bit more to show you some other alternatives and to correct some minor mistakes.
First, you didn't actually post a compiling example, because you forgot to show the included headers <iostream>
and <string>
and also didn't show the using namespace std;
that was implicit in your code.
Second, for the regular for
loop, prefer to keep the loop variable inside the loop, unless you actually need to use it as a return value. Also prefer pre-increment ++i
over post-increment i++
. Furthermore, because you have made sure of the correct loop indices, there is no reason to use the bounds-checked element access at()
over the unchecked []
version.
In C++11, you have the range-for loop which allows for even shorter and more fool-proof code, where I also used auto
where you could have used char
. Unfortunately, there is no reverse range-for loop. The correct index-based reverse for loop is probably easier to read if you use i >= 0
rather than i > -1
.
Then there is an algorithm based loop using std::copy
where you use the iterator interface of std::string
(in particular the reverse iterators rbegin()
and rend()
) to copy each character through an ostream_iterator
that is bound to standard output.
BTW, I used the separator "|"
rather than the newline to see stuff more easier, adapt to your taste. In any case, using std::endl
can have performance implications because it flushes the output buffer every time.
#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()
implicitly returns 0
upon success.
You could use 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;
}
}
Note that you have to increment the variable 'c' (and not decrement it) since this is a reverse iterator.
for(myAnimal.length(); i > -1; i--){
^
this doesn't do anything. you fetch the value and then throw it away.
Did you mean i = myAnimal.length() - 1
?
Because the character positions start at 0, the last character of myAnimal
is at position (myAnimal.length()-1)
not myAnimal.length()
so you want to start the second loop there.