reverse a string with loops - debugging

So this is a function that is getting several errors(which I will list below the function). The point is to take a string and reverse it using loops, and RETURN that reversal. This is what I came up with. I'm pretty sure it's not how its being called, but the function itself, but if asked I will put code of how it's called as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
int reverseString(string userInput)
{	
	int length = userInput.length();
	char reverse[length];
	for(int i = length; i != 0; i--)
	{
		for(int j = 0; j > length; j++)
			reverse[j] = userInput[i];
		cout << userInput[i];
	}

	return reverse;
}


errors:
(4) error C2057: expected constant expression
(4) error C2466: cannot allocate an array of constant size 0
(4) error C2133: 'reverse' : unknown size
(12) error C2440: 'return' : cannot convert from 'char []' to 'int'
1> There is no context in which this conversion is possible

I tried changing line four, maybe I should just call it as a string? and I have no idea whatsoever about the last error - I tried changing to a string function and a void function, but those of you who actually understand programming(unlike myself hehe) know that wont work haha.
My main questions are how do I fix these errors and/or why am I getting these errors?
Last edited on
bump
bump again; still very stuck! Any help is appreciated.
If you want the function to return a string you have to change the return type from int to string.

The size of arrays must be known at compile time. length is not a compile time constant so it fails to compile. Why not use an std::string instead of char array?
std::string has reverse iterators ;)
http://www.cplusplus.com/reference/string/string/rbegin/
Last edited on
closed account (zb0S216C)
Compiler wrote:
(4) error C2057: expected constant expression

The length of an array must be a constant. length is not a constant.

Compiler wrote:
(12) error C2440: 'return' : cannot convert from 'char []' to 'int'
reverseString() is supposed to return an int, not a char* (pointer to a char).

A better way to do this is to use std::string instead of char[]. For example:

1
2
3
4
5
6
7
8
9
10
std::string Reverse(const std::string &String)
{
    std::string::const_iterator Itor((String.end() - 1));
    std::string Out;

    for(; Itor >= String.begin(); --Itor)
        Out.push_back(*Itor);

    return(Out);
}

If you don't understand something, just ask :)

Wazzak
Last edited on
I'm a beginner myself, but here are my suggestions:
- Make sure userInput (I guess that's input from the user,, maybe?) can never be 0. You've made return have the value of 0 since userInput is 0. I don't know how this is zero since I don't see the prior code, so just make sure it can never be 0.
- The last error probably has something to do with the rest, the surrounding, code.
- You should make sure 'return' returns a same kind of value as it did before, or you have to convert it yourself. (With this, I mean: In line 4 you made it a char value, and in 12 it is an int at once. It seems like you're trying to change it's size by declaring it to a new capacity (in this case, j))

Try to change return for yourself first, and if that doesn't work..
Just show the new errors, I guess.
Last edited on
Thank you for all of your replies.

Peter87 - Good suggestion. I will try using a string array, however the function is only handling one char at a time, which is why I chose a char array.

L B - as pointed out in the title and the question, I need to use loops. I have already made a separate function using reverse iterators.

Framework

The length of an array must be a constant. length is not a constant.


So it should clear up if I call it a const int? As for your code, I'm not accustomed to not "using namespace std" I don't understand it very well with all of the "std::"s around. we haven't been using iterators yet, but if you have a link to a guide on them, I would appreciate it. Also, I'm pretty sure we're not supposed to push anything... we're supposed to send a new string back to the main function. Thank you for your thorough answer, it is highly appreciated.


NutHoofd

- Make sure userInput (I guess that's input from the user,, maybe?) can never be 0.


userInput is a string from the user. It will not be zero, and if it were, it would not take the value of zero(which is an int), because it is a string, as it was declared in the function.


It seems like you're trying to change it's size by declaring it to a new capacity (in this case, j))


It's not actually declaring a capacity it's filling the values of an array. If I have some array[2] I do not change it's capacity by declaring the values
array[0] = 1;
array[1] = 2;
array[2] = 3;

it is only the declaration of the variable that holds the capacity, I'm actually filling the values of the array in that loop.

That's not to be rude whatsoever, it's to be helpful, because if you use C++, it's a nifty tool to use in arrays(at least it has been for me).
EyesOfHope wrote:
as pointed out in the title and the question, I need to use loops. I have already made a separate function using reverse iterators.
You cannot use iterators without using loops ;p
EyesOfHope wrote:
Good suggestion. I will try using a string array, however the function is only handling one char at a time, which is why I chose a char array
A std::string can be used just like a character array (you can use the [] operator on it, so long as you don't go out of bounds)
Last edited on
L B wrote

You cannot use iterators without using loops ;p


I actually didn't know that. This is the first time we've used any of these string functions. I'll look it up, but if you have any sample code to help me understand, that'd be awesome.
There is sample code in the link from earlier if you scroll down that does exactly what you are doing (reversing a string):
http://www.cplusplus.com/reference/string/string/rbegin/
One of the first things I found too. I guess I'm such a n00b that I don't understand what all is going on. We haven't learned any of this in my class, so I feel shortsighted when looking it up.

1
2
3
4
5
6
7
8
9
10
11
12
13
// string::rbegin and string::rend
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string str ("now step live..."); // can I do this from the userInput?
  string::reverse_iterator rit; // why does this have to be declared with string::?
  for ( rit=str.rbegin() ; rit < str.rend(); rit++ )
    cout << *rit;  //why does this have a * in front of it?
  return 0;
}

copied from http://www.cplusplus.com/reference/string/string/rbegin/
closed account (zb0S216C)
eyesofhope wrote:
As for your code, I'm not accustomed to not "using namespace std" I don't understand it very well with all of the "std::"s around. we haven't been using iterators yet, but if you have a link to a guide on them, I would appreciate it. Also, I'm pretty sure we're not supposed to push anything... we're supposed to send a new string back to the main function.

I'll tell you what my code does.

Reverse() is a function that returns a std::string, and takes a std::string object as an argument (called String). Pay no attention to the ampersand (&) for the moment.

The const_iterator is an iterator (look at the bottom of this post, marked A) that's used to pass through String. The iterator was set to the end of String (point B). I then declared another std::string object called Out, which will store the string that will be given back to main().

for Loop, Condition: While Itor is not at point A of String.
for Loop, Increment/Decrement: Decrements Itor (moving towards point A).

While the for loop's condition is false, the character pointed to by Itor is added to the end of Out.

When the loop is finished, Out is returned.

A) Without going into depth, an iterator is an object that moves from 1 point to another. An array, for example, has a point A (the first element) and a point B (the last element). An iterator would move from point A to point B. The value of an iterator is the element the iterator refers to.

Also, the std:: is an alternative, as well as using std::cout, for using namespace std;. What's the difference? using namespace std causes name conflicts, and destroys the purpose of namespaces (a simple topic, but I won't explain them here).

Wazzak
Last edited on
Revised code(While all of the advice is helpful to me, and helps me understand C++ better, I had to do some of my own research and write code that would not only be my own work, but also acceptable to my instructor)

New Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string reverseString(string userInput)
{	
	int maxStringSize = 50;
	string reverse[maxStringSize];
	int count = 1;
	for(int i = userInput.length(); i != 0; i--)
	{
		reverse[count] = userInput[i];
		cout << userInput[i];
		count ++;
	}
	string backwards(reverse, maxStringSize);

	return backwards;
}


New Problem:(Gibberish to me... can anyone translate?)

error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &,unsigned int,unsigned int)' : cannot convert parameter 1 from 'std::string [50]' to 'const std::basic_string<_Elem,_Traits,_Ax> &'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> Reason: cannot convert from 'std::string [50]' to 'const std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
Last edited on
closed account (zb0S216C)
eyesofhope wrote:
string reverse[maxStringSize];

...creates an array of std::string objects, not an array of char. Here's how it's supposed to be done:

1
2
3
4
std::string My_string;

// Add a new character to the end of the string:
My_string.push_back('A');

Wazzak
EyesOfHope wrote:
One of the first things I found too. I guess I'm such a n00b that I don't understand what all is going on. We haven't learned any of this in my class, so I feel shortsighted when looking it up.
1
2
3
4
5
6
7
8
9
10
11
12
13
// string::rbegin and string::rend
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string str ("now step live..."); // "can I do this from the userInput?" - yes, you can, this string was just hard-coded as an example
  string::reverse_iterator rit; // "why does this have to be declared with string::?" Because reverse_iterator is a class inside of the string class, just like std::string is a class inside of the std namespace
  for ( rit=str.rbegin() ; rit < str.rend(); rit++ )
    cout << *rit;  //"why does this have a * in front of it?" Because iterators can be treated like pointers; you dereference the iterator to get the char it is iterated to
  return 0;
}

copied from http://www.cplusplus.com/reference/string/string/rbegin/


EDIT: Sorry for the obscenely wide post. The code tags really need linewrapping.
Last edited on
Topic archived. No new replies allowed.