简体   繁体   中英

How to reverese a c-style string

I would like to reverse a c-style string and came up with the following code.

Play with the code

#include <iostream>

void reverse_c_str(char *c)
{
    char *new_c = c;
    for (; *new_c; ++new_c){}    // find '\0'
    --new_c;                     // new_c is now at the actual last char, which is 'g'
    while (c < new_c)            // swap chars
    {
        char tmp = *c;
        *c = *new_c; // crash
        *new_c = tmp;
        --new_c;
        ++c;
    }
}

int main()
{
    char *c = "my string";
    reverse_c_str(c);
    std::cout << c << '\n';
}

Unfortunately, my code has an error, which I marked with // crash . Why does this line crash?

"my string" is a string literal, it is const .

It can be cast to a non-const char * for reasons of compatibility with C, but modifying a constant invokes undefined behavior . In some cases the OS will prevent it (as when it's stored in a read-only section), which is probably what you're observing.

Make a copy of the string in automatic storage, then you'll be able to modify it:

int main()
{
    char c[] { "my string" };
    reverse_c_str(c);
    std::cout << c << '\n';
}

And of course there is a templated soultion:

#include <cstring>

template<std::size_t N>
void reverse_c_str(char (&str)[N]) {
    std::size_t len = N-1;
    for (std::size_t i = 0; i < len/2; ++i) {
        str[i] ^= str[len-i-1];
        str[len-i-1] ^= str[i];
        str[i] ^= str[len-i-1];
    }
}

int main() {
    char c[] {"123"};
    reverse_c_str(c);

    char c2[] {""};
    reverse_c_str(c2);

    char c3[] {"4321"};
    reverse_c_str(c3);

    return 0;
}

Use std::swap and std::strlen . I made example for you here .

#include <iostream>
#include <cstring>

void reverse_c_str(char *c) {
    int length = std::strlen(c);
    for (int i = 0; i < length / 2; i++)
        std::swap(c[i], c[length - i - 1]);
}

int main()
{
    char c[] { "my string" };
    reverse_c_str(c);
    std::cout<<c << std::endl;
    return 0;
}

Output:
gnirts ym

Another one version of function reverse_c_str

void reverse_c_str(char *c) {
    if(*c) {
        for(auto begin = c, end = c + std::strlen(c) - 1; 
            begin < end; ++begin, --end
            ) {
            std::swap(*begin, *end);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM