Wskaźniki w C do stringów...

Odpowiedz Nowy wątek
2019-05-12 07:09
0

Jest sobie pewien kod w C:

#include <stdio.h>

char * LineToStr(char *in_s, int in_l, char * separator){

  char *s = in_s;
  int i;
  char *a,*b;

  /* usuwam segmenty niepotrzebne przed */
  for (i=2;i<=in_l;i++){
    if (s=strstr(s,separator)) s++;
  }

  /* usuwam segmenty niepotrzebne po */
  if (a=strstr(s,separator)){
    a++;
    a="\0";
    //memcpy(&s[1],"\0",1);

//    printf("Wskaźnik a=%s\n",a);
  }

  return s;
}

void main(){
  printf("tekst=%s\n",LineToStr("jeden;dwa;trzy;cztery;pięć",2,";"));
}

I czy ktoś mi wytłumaczy dlaczego ten C jest taki oporny i nie działa?
Mam pie...lony wskaźnik do stringu a, który po wyk. strstr wskazuje podobno na znaczek ';' w s, to chce w tym miejscu uciąć ten teskt, wstawiam '0' do a, a skoro a wskazuje na ';' w s, to w s powinno się te '0' znaleźć, a nie znajduje...

Czyżby w C nie działały wskaźniki na stringach???

Pozostało 580 znaków

2019-05-12 08:17
0
char* a;
...
a="\0";

Przyjrzyj się.

Pozostało 580 znaków

2019-05-12 09:09
0

W a to działa. Nie ważne, czy zrobię a="\0" czy a='\0' - oba zapisy mój kompilator łyka bez problemów, jeśli chodzi tobie o rodzaj apostrofów.
I jak wyświetlam zawartość a to pokazuje mi pusty string, gdy ta linijkę zakomentuję, wtedy pokazuje mi to co w s, czyli cały string.

Ale nie rozumiem tego, że skoro a to wskaźnik do s, to jakakolwiek zmiana w nim, powinna powodować zmianę w s, a nie robi tego! I to jest właśnie problem tego kodu, który próbuję zrozumieć.
W sieci znalazłem mnóstwo przykładów jak to w C fantastycznie działają wskaźniki, ale wszystkie to przykłady liczb, np. INT.

Np. taki kod:

int a = 5;
int b;
b=a;
b = 4;
printf("%d",a) -> wyświetli 4. Wskaźnik zmienił zawartość 5 na 4, prawidłowo!

I dokładnie to samo chciałbym uzyskać we wskaźniku, który wskazuje na znak w stringu.
Niestety jakkolwiek próbuję to zrobić, c albo pokazuje mi błąd, albo wywala się naruszeniem pamięci.

W pascalu to robi się po prostu z palca, nie ma znaczenia na co wskazuje wskaźnik, czemu w C nie da się zrobić tego tak samo prosto.
To właśnie usiłuję zrozumieć.

Pozostało 580 znaków

2019-05-12 09:47
0
samueladama napisał(a):

W a to działa. Nie ważne, czy zrobię a="\0" czy a='\0' - oba zapisy mój kompilator łyka bez problemów, jeśli chodzi tobie o rodzaj apostrofów.
I jak wyświetlam zawartość a to pokazuje mi pusty string, gdy ta linijkę zakomentuję, wtedy pokazuje mi to co w s, czyli cały string.

Tłumacząc na Pascala, robisz coś takiego i dziwisz się że napis się nie zmienia:

var napis:array[0..255] of char = 'Ala ma kota.';

var wsk:pchar;

begin
  wsk := @napis;
  wsk := #0;
  writeln(napis);
end.

Zmieniasz wartość wskaźnika (przypisujesz doń adres innego stringa), a nie modyfikujesz wskazywany string.

edytowany 1x, ostatnio: Azarien, 2019-05-12 09:48

Pozostało 580 znaków

2019-05-12 10:35
0

Masz rację, niestety kodu

*a = #0;

kompilator nie akceptuje, zaś kod:
a<=#0;
jest akceptowany, ale nie daje pożądanego wyniku.

W takim razie jak zapisać w c, coś, co w pascalu wygląda następująco:

var s: string;
      p: ^char;
begin
  s:='1234556';
  p=&s[2];
  p^:='0';
  writeln(s); //=> '103456' (wynik oczekiwany)
end;

Pozostało 580 znaków

2019-05-12 10:46
0
#include <stdio.h>

char * LineToStr(char *in_s, int in_l, char * separator){

  char *s = in_s;
  int i;
  char *a,*b;

  /* usuwam segmenty niepotrzebne przed */
  for (i=2;i<=in_l;i++){
    if (a=strstr(s,separator)) a++;
  }

  /* usuwam segmenty niepotrzebne po */
  if (a=strstr(s,separator)){
    a++;
    *a='\0';
    return s;
    //memcpy(s,'\0',1);

//    printf("Wskaźnik a=%s\n",a);
  }

  return in_s;
}

void main(){
  printf("tekst=%s\n",LineToStr("jeden;dwa;trzy;cztery;pięć",1,";"));
}

Kod się wywala:

[[email protected] C]$ ./compile
demo.c: In function ‘LineToStr’:
demo.c:12:11: warning: implicit declaration of function ‘strstr’ [-Wimplicit-function-declaration]
     if (a=strstr(s,separator)) a++;
           ^~~~~~
demo.c:12:11: warning: incompatible implicit declaration of built-in function ‘strstr’
demo.c:12:11: note: include ‘<string.h>’ or provide a declaration of ‘strstr’
demo.c:2:1:
+#include <string.h>

demo.c:12:11:
     if (a=strstr(s,separator)) a++;
           ^~~~~~
demo.c:16:9: warning: incompatible implicit declaration of built-in function ‘strstr’
   if (a=strstr(s,separator)){
         ^~~~~~
demo.c:16:9: note: include ‘<string.h>’ or provide a declaration of ‘strstr’
./compile: linia 3:  4490 Naruszenie ochrony pamięci   (zrzut pamięci) ./a.out

Dlaczego?

Pozostało 580 znaków

2019-05-12 10:55
0

Wszystko masz napisane. Brakuje nagłówka <string.h>

Powiedz co konkretnie chcesz osiągnąć, bo *a = '0' i *a = '\0' to dwie różne rzeczy.

Pozostało 580 znaków

2019-05-12 11:15
0
samueladama napisał(a):

Masz rację, niestety kodu

*a = #0;

kompilator nie akceptuje, zaś kod:

Bo to nie jest C.

*a = '\0';

Pozostało 580 znaków

2019-05-12 12:07
0

Chcę zmieniać zawartość stringu za pomocą wskaźników, nie ważne czy to będzie 'A' czy '\0', bo to bez znaczenia, skoro ani jednego, ani drugiego nie udaje mi się wpisać w ten sposób.

Pozostało 580 znaków

2019-05-12 12:21
0

Znalazłem taki kod w necie:

char *Slowa_Na_Duze( char* tekst )

        {

           char *wsk = tekst;

           if( !*wsk )        // jeżeli tekst pusty to zakończ działanie

               return(tekst);

           *wsk = toupper( *wsk );              // zamiana pierwszej litery

           while( *++wsk )

               if( *(wsk-1) == ' '  )                 // jeżeli poprzedzający znak jest spacją

                   *wsk = toupper( *wsk );       // zamiana znaku na dużą literę

           return( tekst );

        } //------------------------------------------------------------------------ Slowa_Na_Duze

Próbuję zrobić coś podobnego i u mnie to nie działa. Wytłumaczcie mi, co robię źle.
Bo jak ja u siebie próbuję podstawić jakikolwiek znak pod string podany w parametrze funkcji, to niestety zawsze kończy się to naruszeniem pamięci.

Pozostało 580 znaków

2019-05-12 12:26
0

Dobra nie ważne, pie...przyć ten C, strasznie ograniczony ten język... Widocznie to ponad siły tego tak przez niektórych idealizowanego języka.
C dobry jest do liczb, nawet całkiem dobrze sobie z nimi radzi, niestety ze stringami nie radzi sobie wcale, nawet wy nie potraficie pomóc. Dzięki, odpuszczam sobie problem.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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