Odwracanie istniejącego w pamięci łańcucha znaków w C

0

Napisanie funkcji zwracającej nowy łańcuch w dynamicznie zaalokowanej pamięci nie jest problemem. Walczę z funkcją odwracającą łańcuch znaków w C, ale bez zwracania wskaźnika do nowego łańcucha. To powinno szczególnie proste, gdyż mamy pewność, że długość łańcucha nie zmieni się.

Pierwszy pomysl, podaje go poniewaz zastanawia mnie czemu nie moge skopiowac dowolnego lancucha znakow na adres wskazywany przez *str?

int reverse(char** str)
{
  int len = strlen(*str);
  char* eptr = *str + len - 1;
  char* bptr = *str;
  char buf[len + 1];
  char* bufptr = buf;
  
  while(*bptr) {
    *bufptr = *eptr;
    --eptr; ++bufptr; ++bptr;
  }
  
  // po wyswietleniu widze, ze otrzymalem to co chcialem
  // printf("str: %s buf: %s\n", *str, buf);
  // powoduje segmentation fault
  strcpy(*str, buf);
}

Tak wydaje mi sie prosciej i ladniej:

int reverse(char** str)
{
  int len = strlen(*str);
  char* copy = strdup(*str);
  char* strptr = *str;
  char* endptr = copy + len - 1;
  while(*strptr) {
    // segmentation fault w nastepnej linijce (nie chce pozwolic na zapis)
    *strptr = *endptr;
    --endptr; ++strptr;
  }
  free(copy);
}

Tylko, ze program nie pozwala mi na zmiane mimo, ze wskazniki wskazuja na wlasciwe elementy (wyklada sie przy przepisaniu

*strptr = *endptr;

). Dlaczego?

Pozdrawiam,

0

Nie pokazałeś jak to wywołujesz.

0
  1. nie potrzebujesz parametrów char**. wystarczy char*
  2. twoje funkcje nic nie zwracają. daj albo void albo nadaj im sensowną wartość zwracaną (np. długość stringa)
  3. w pętli jedziesz do samego końca stringa. w ten sposób go odwrócisz dwukrotnie, w rezultacie „nic się nie stanie”.
void reverse(char *str)
{
  int len = strlen(str);
  int half = len / 2;
  int i;
  for (i=0;i<half;i++)
  {
     char c = str[i];
     str[i] = str[len-i-1];
     str[len-i-1] = c;
  }
}
0

char buf[len + 1]; - tak NIE MOŻNA jeśli len jest zmienną!

W C99 tez nie mozna jezeli ta zmienna ma zawsze stala wartosc w zasiegu funkcji?

Nie pokazałeś jak to wywołujesz.

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

void reverse(char** str)
{
  int len = strlen(*str);
  char* copy = strdup(*str);
  char* strptr = *str;
  char* endptr = copy + len - 1;
  while(*strptr) {
    // segmentation fault w nastepnej linijce (nie chce pozwolic na zapis)
    *strptr = *endptr;
    --endptr; ++strptr;
  }
  free(copy);
}


int main()
{
  char* tekst = "Tekst do odwrocenia.";
  reverse(&tekst);
  printf("%s\n", tekst);
}

Sprobowalem na tej funkcji:

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

void reverse(char *str)
{
  int len = strlen(str);
  int half = len / 2;
  int i;
  for (i=0;i<half;i++)
  {
     char c = str[i];
     str[i] = str[len-i-1];
     str[len-i-1] = c;
  }
}

int main()
{
  char* tekst = "Tekst do odwrocenia.";
  reverse(tekst);
  printf("%s\n", tekst);
}

Znowu blad segmentacji (pewnie ma to zwiazek z tym, ze jest to staly lancuch znakow). Ale raczej mozna to obejsc bez kopiowania do nowego miejsca.

0

W C99 tez nie mozna jezeli ta zmienna ma zawsze stala wartosc w zasiegu funkcji?
w C99 można.
stałość zmiennej nie ma znaczenia: liczy się tylko jej wartość w momencie tworzenia tablicy:

int n = 10;
int tablica[n]; // ok, tablica[10]
n = 15; // tablica NIE zmieni od tego rozmiaru

Znowu blad segmentacji (pewnie ma to zwiazek z tym, ze jest to staly lancuch znakow).
No pewnie że tak.

zresztą u mnie GCC wyrzuca ostrzeżenie:

a.c: In function 'int main()':
a.c:20:17: warning: deprecated conversion from string constant to 'char*'

Ale raczej mozna to obejsc bez kopiowania do nowego miejsca.

char tekst[] = "Tekst do odwrocenia.";
0

DAMN, taka istotna pierdoła. No nic dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1