使用指针在c中反转字符串

时间:2018-06-24 22:34:25

标签: c string pointers reverse

我正在尝试使用指针来反转字符串,但似乎不起作用,这是什么问题?输出为olllo,但应为olleh

#include <stdio.h>   
#include <string.h>   
#include <stdlib.h>   


void reverse(char *cadena){

    size_t len = strlen(cadena);
    char *end= cadena;
    char *aux = cadena;
    while(*++end){}
    --end; //end points to a

    for(;len;--len){
        *aux++ = *end--;

    }

}

int main()
{

    char buffer[] = "hello";
    reverse(buffer);
    printf("%s",buffer);


    return 0;
}

3 个答案:

答案 0 :(得分:3)

该行:

*aux++ = *end--;

不交换任何东西。它只是分配左侧的值。您总是会遇到以字符串右半部分为中心的回文。对于交换逻辑,您应该执行以下操作:

char tmp = *aux;
*aux = *end;
*end = tmp;

此外,您不应该真正遍历整个字符串。实际上,这意味着将字符串反转,然后再次将其反转。只需在遍历字符串的一半时应用交换逻辑,就可以了:

void reverse(char *cadena) {
    if(cadena != NULL){                                 // add some checks...    
        size_t len = strlen(cadena);
        char *end = cadena + (len > 1 ? len - 1 : 0);   // ...for safety    
        char *aux = cadena;

        for (len /= 2; len; --len) {
            char tmp = *aux;
            *aux++ = *end;
            *end-- = tmp;
        }
    }
}

答案 1 :(得分:1)

解决您的错误

循环的问题在于,当您尝试将字符反转到位时,最终会交换已交换的字符。

我将尝试通过显示每次迭代中发生的事情来进行解释。 您可以在每次迭代中的每次交换之后看到cadena的初始内容和最终的res|和指针aux当前指向的位置:

end

在解决方案上。

我到位的len = 5 aux | h e l l o end | res: o e l l o len = 4 aux | h e l l o end | res: o l l l o len = 3 aux | h e l l o end | res: o l l l o len = 2 aux | h e l l o end | res: o l l l o len = 1 aux | h e l l o end | res: o l l l o len = 0 => break the loop this one

reverse

一些关键点:

  • 注意使用void reverse(char *str) { if (!str || !(*str)) return; char *end = str + strlen(str) - 1; while (str < end) { char tmp = *str; *str++ = *end; *end-- = tmp; } } 查找字符串的最后一个字符
  • 您应该迭代直到开始和结束指针相遇。否则,请重新反转字符串

答案 2 :(得分:0)

您的代码中存在三个重要错误:

  1. 在此代码段中前进到最后时,您对空字符串的处理不正确:

    char *end= cadena;
    // Irrelevant: char *aux = cadena;
    while(*++end){}
    --end; //end points to a
    

    无论如何,您已经有了字符串长度,所以只需添加它即可。

    修复此错误时,请确保仅创建有效的指针,即指向对象或位于对象之后的指针。

  2. 您要遍历整个字符串的长度,而不是一半。如果您实际上交换了元素,那么您将交换所有内容两次,这是非常昂贵的nop:

    for(;len;--len){
    
  3. 您正在复制而不是交换。您没有保存您覆盖的值,也没有将其存储回它所属的位置。

        *aux++ = *end--;
    }
    

固定代码:

void reverse_string(char* s) {
    char* e = s + strlen(s);
    while (s < e) {
        char t = *s;
        *s++ = *--e;
        *e = t;
    }
}