Reputation: 99
I'm currently doing a programming exercise from a C++ book for beginners. The task reads as follows: "Write a function that reverses the characters in a text string by using two pointers. The only function parameter shall be a pointer to the string."
My issue is that I haven't been able to make the characters swap properly, see the output below. (And I also made the assumption that the function parameter doesn't count, hence why I'm technically using three pointers).
I am almost certain that the problem has to do with the for loop. I wrote this pseudocode:
- Assign value of element number i in at_front to the 1st element in transfer_back.
- Assign value of element number elem in at_back to element number i in at_front.
- Assign value of the 1st element in transfer_back to element number elem in at_back.
- Increment i, decrement elem. Repeat loop until !(i < elem)
I wasn't sure whether of not I was supposed to take the null terminator into account. I tried writing (elem - 1) but that messed up with the characters even more so I've currently left it as it is.
#include <iostream>
#include <string>
using namespace std;
void strrev(string *at_front) {
string *transfer_back = at_front, *at_back = transfer_back;
int elem = 0;
while(at_back->operator[](elem) != '\0') {
elem++;
}
for(int i = 0; i < elem; i++) {
transfer_back->operator[](0) = at_front->operator[](i);
at_front->operator[](i) = at_back->operator[](elem);
at_back->operator[](elem) = transfer_back->operator[](0);
elem--;
}
}
int main() {
string str = "ereh txet yna";
string *point_str = &str;
strrev(point_str);
cout << *point_str << endl;
return 0;
}
Expected output: "any text here"
Terminal window: "xany text her"
The fact that the 'x' has been assigned to the first element is something I haven't been able to grasp.
Upvotes: 0
Views: 68
Reputation: 7820
Here is the correct answer
void strrev(string *at_front) {
string *at_back = at_front;
char transfer_back;
int elem = 0;
while(at_back->operator[](elem) != '\0') {
elem++;
}
for(int i = 0; i <elem; i++) {
transfer_back = at_front->operator[](i);
at_front->operator[](i) = at_back->operator[](elem);
at_back->operator[](elem) = transfer_back;
elem--;
}
}
Let me explain why you have that error. string *transfer_back = at_front
those two are pointed to the same reference, that is why when you change transfer_back->operator[](0) = at_front->operator[](i);
this change will reflect in at_front string as well.
Upvotes: 1
Reputation: 20141
"Write a function that reverses the characters in a text string by using two pointers. The only function parameter shall be a pointer to the string."
This sounds to me like the question addresses C strings but not std::string
.
Assuming my feeling is right, this could look like:
#include <iostream>
#include <string>
void strrev(char *at_front) {
char *at_back = at_front;
if (!*at_back) return; // early out in edge case
// move at_back to end (last char before 0-terminator)
while (at_back[1]) ++at_back;
// reverse by swapping contents of front and back
while (at_front < at_back) {
std::swap(*at_front++, *at_back--);
}
}
int main() {
char str[] = "ereh txet yna";
strrev(str);
std::cout << str << '\n';
return 0;
}
Output:
any text here
Note:
I stored the original string in a char str[]
.
If I had used char *str = "ereh txet yna";
I had assigned an address of a constant string to str
. This feels very wrong as I want to modify the contents of str
which must not be done on constants.
strrev()
:
The at_back[1]
reads the next char
after address in at_back
. For a valid C string, this should be always possible as I excluded the empty string (consisting of 0-terminator only) before.
The swapping loop moves at_front
as well as at_back
. As the pointer is given as value, this has no "destructive" effect outside of strrev()
.
Concerning std::swap(*at_front++, *at_back--);
:
The swapping combines access to pointer contents with pointer increment/decrement, using postfix-increment/-decrement. IMHO, one of the rare cases where the postfix operators are useful somehow.
Alternatively, I could have written:
std::swap(*at_front, *at_back); ++at_front; --at_back;
Please, note that std::string
is a container class. A pointer to the container cannot be used to address its contained raw string directly. For this, std::string
provides various access methods like e.g.
std::string::operator[]()
std::string::at()
std::string::data()
Upvotes: 1