Funkcja strcat() a jej argumenty.

Funkcja strcat() a jej argumenty.
MA
  • Rejestracja:około 11 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Witam
Pisząc prosty programik(poniżej) chciałem sprawdzić czy w funkcji strcat jako pierwszy argument mogę użyć dynamicznie alokowanej tablicy.
Ten zapis powodował zawieszenie programu

Kopiuj
 strcat(t,"0")

Z takim zapisem wszystko działało strcat(p,"0")

Kopiuj
. 
Gdy zrobiłem zwykły wskaźnik to wtedy mogłem podać t jako argument strcat i również program działał 
```cpp
  char*t;// 1
    char p[10]="zero";
    t=p;

Dlaczego tak się dzieje ? Gdy dynamicznie stworze tablice to t jest wskaznikiem na pierwszy element tablicy?

Kopiuj
  char*t= new char[10];
Kopiuj
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
using namespace std;

int main(int argc, char *argv[])
{
    char*t= new char[10];
    char p[10]="zero";
    t="zero";
    
    for(int i=0;i<10;i++)
    {
            cout<<"kolumna : "<<i<<" wartosc "<<p<<endl;
            if((p[i])=='\0') cout<<i<< "zero"<<endl;
    }
       for(int i=0;i<10;i++)
    {
            cout<<"kolumna : "<<i<<" wartosc "<<t<<endl;
            if((t[i])=='\0') cout<<i<< "zero"<<endl;
    }
    
    strcat(p,"0");
    cout<<"p "<<p<<endl;
    getch();
    return EXIT_SUCCESS;
}

 

Mateo:D
msm
Administrator
  • Rejestracja:około 16 lat
  • Ostatnio:5 miesięcy
1

To nie wina strcat.

Ale najpierw coś trochę innego:

Kopiuj
#include <stdio.h>
#include <ctype.h>

int main() {
    char *str = "asdf";
}
Kopiuj
$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:5:17: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
     char *str = "asdf";

Nawet bez żadnych opcji ostrzeżeń, kompilator mówi Ci że coś jest nie w porządku.

Literały napisowe są immutable. Nawet taki prosty kod to UB:

Kopiuj
char * str = "Hello!";
str[1] = 'a';

A dlaczego o tym piszę.
Bo to:

Kopiuj
char p[10]="zero";

To kompletnie co innego niż to:

Kopiuj
char*t= new char[10];
t="zero";

Drugie przypisanie oznacza tutaj (ważne żebyś to zrozumiał:) coś w rodzaju "zapomnij kompletnie o zaalokowanej tablicy 10elementowej (powodując memleak), a zamiast tego przypisz do t napis "zero" (który jest immutable, jak wyżej napisano).

Chodziło Ci prawdopodobnie o coś takiego:

Kopiuj
char*t= new char[10];
strcpy(t,"zero");

("skopiuj napis 'zero' do tablicy na którą wskazuje wskaźnik t" -> dokładnie to miałeś na myśli)

edytowany 3x, ostatnio: msm
MA
  • Rejestracja:około 11 lat
  • Ostatnio:około 9 lat
  • Postów:7
0

Dzięki Wielkie dokładnie to miałem na myśli.
Gdy zrobiłem tak ja powiedziałeś to wszystko działa:).
Czyli po inicjalizacji zmiennej jeżeli chcę wpisać inny napis to tylko i wyłącznie za pomocą strcpy bez znaczenia czy jest to char[]czy tez char*t? :)
Trochę poczytałem i znalazłem coś takiego

Deklarując napis można nie określać jego długości, kompilator przydzieli wtedy
automatycznie odpowiedni rozmiar pamici (uwzgldniajc ostatni znak ’\0’), np.
char *txt = ”To jest napis” ; lub char txt[] = ” To jest napis” ;
W powyższy sposób można nadawać wartość łańcuchowi znaków tylko przy
jego deklaracji. Błędnym zatem jest poniższy zapis:
char txt[10];
txt = ” Pies” ; - taki zapis nie jest poprawny.
Prawidłowy zapis wymaga wykorzystania funkcji strcpy() z pliku nagłówkowego
string.h:
char txt[10];
strcpy(txt,” Pies” );

Według tego to co napisałeś na początku

Kopiuj
 char *str = "asdf";

Jeżeli dobrze zrozumiałem to można tak inicjalizować napis?


Mateo:D
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:dzień
1

Można tak inicjalizować ale nie możesz w takim napisie zmienić liter albo coś dopisać.
Co najwyżej przestawić na coś innego: str="zxcv";


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.