обратная строка в c с использованием указателей - PullRequest
0 голосов
/ 25 июня 2018

Я пытаюсь перевернуть строку, используя указатели, но кажется, что она не работает, в чем проблема?вывод 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 голосов
/ 25 июня 2018

Устранение вашей ошибки

Проблема с вашим циклом заключается в том, что при попытке поменять местами символы вы меняете местами уже поменявшиеся символы.

I 'Я попытаюсь объяснить, показывая, что происходит в каждой итерации.Вы можете увидеть начальное содержимое 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

На решение ..

Мое место 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;
    }
}

Некоторые ключевые моменты:

  • обратите внимание на использование strlen для поиска последнего символа строки
  • Вы должны выполнять итерации, пока не встретятся начальный и конечный указатели.В противном случае вы перевернете строку
0 голосов
/ 25 июня 2018

В вашем коде есть три важные ошибки:

  1. Вы неправильно обрабатываете пустую строку при переходе к концу этого фрагмента:

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

    В любом случае,у вас уже есть длина строки, поэтому просто добавьте ее.

    При исправлении этой ошибки убедитесь, что вы создаете только действительные указатели, то есть объекты или непосредственно за ними.

  2. Вы идете по всей длине, а не по половине.Если вы на самом деле поменялись местами, вы бы дважды поменяли все местами, довольно дорогое примечание:

    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;
    }
}
0 голосов
/ 25 июня 2018

Строка:

*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;
        }
    }
}
...