开发者

Reversing a string, weird output c++

Okay, so I'm trying to reverse a C style string in C++ , and I'm coming upon some weird output. Perhaps someone can shed some light?

Here is my code:

 int main(){    

    char str[] = "string";
    int strSize = sizeof(str)/sizeof(char);

    char str2[strSize];

    int n = strSize-1;
    int i =0;


    while (&str+n >= &str){ 
        str2[i] = *(str+n);         
        n--;
        i++;
    }

    int str2size = sizeof(str)/sizeof(char);
    int x;

    for(x=0;x<str2size;x++){
        cout << str2[x];
    }

}

The basic idea here is just making a pointer point to the end of the string, and then reading it in backwards into a new array using pointer arithmetic.

In this particular case, I get an output of: " gnirts" There is an annoying space at the beginning of an开发者_运维技巧y output which I'm assuming is the null character? But when I try to get rid of it by decrementing the strSize variable to exclude it, I end up with some other character on the opposite end of the string probably from another memory block.

Any ideas on how to avoid this? PS: (would you guys consider this a good idea of reversing a string?)


A valid string should be terminated by a null character. So you need to keep the null character in its original position (at the end of the string) and only reverse the non-null characters. So you would have something like this:

str2[strSize - 1] = str[strSize - 1]; // Copy the null at the end of the string

int n = strSize - 2; // Start from the penultimate character


There is an algorithm in the Standard Library to reverse a sequence. Why reinvent the wheel?

#include <algorithm>
#include <cstring>
#include <iostream>

int main()
{
   char str[] = "string";

   std::reverse(str, str + strlen(str)); // use the Standard Library

   std::cout << str << '\n';
}


@ildjarn and @Blastfurnace have already given good ideas, but I think I'd take it a step further and use the iterators to construct the reversed string:

std::string input("string");

std::string reversed(input.rbegin(), input.rend());

std::cout << reversed;


I would let the C++ standard library do more of the work...

#include <cstddef>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    typedef std::reverse_iterator<char const*> riter_t;

    char const str[] = "string";
    std::size_t const strSize = sizeof(str);
    char str2[strSize] = { };
    std::copy(riter_t(str + strSize - 1), riter_t(str), str2);
    std::cout << str2 << '\n';
}


 while (&str+n >= &str){

This is nonsense, you want simply

while (n >= 0) {

and

 str2[i] = *(str+n);

should be the much more readable

str2[i] = str[n];


Your while loop condition (&str+n >= &str) is equivalent to (n >= 0).

Your *(str+n) is equivalent to str[n] and I prefer the latter.

As HappyPixel said, your should start n at strSize-2, so the first character copied will be the last actual character of str, not the null termination character of str.

Then after you have copied all the regular characters in the loop, you need to add a null termination character at the end of the str2 using str2[strSize-1] = 0;.

Here is fixed, working code that outputs "gnirts":

#include <iostream>
using namespace std;
int main(int argc, char **argv){    
    char str[] = "string";
    int strSize = sizeof(str)/sizeof(char);

    char str2[strSize];

    int n = strSize-2;  // Start at last non-null character
    int i = 0;

    while (n >= 0){ 
        str2[i] = str[n];         
        n--;
        i++;
    }
    str2[strSize-1] = 0;   // Add the null terminator.

    int str2size = sizeof(str)/sizeof(char);
    int x;

    cout << str2;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜