ale każdy kto się zna od razu dostrzeże błąd
Niby tak, ale ten tekst jest raczej dla początkujących, więc oni tego "drobnego" błędu nie dostrzegą.
powinno oczywiście być:
- Kod: Zaznacz cały
char * Buf = new char;
...
Niestety nie. Alokujesz jeden bajt i przy odczycie jakiegoś wyrazu wyjedziesz poza zakres tablicy - podając operatorowi >> wskaźnik
char* dajesz do zrozumienia, że chcesz czytać ze strumienia c-stringi, a nie pojedynczy znak. Nawet jakbyś wpisał jedną literę, to i tak byłby błąd, bo jeszcze zero musiałoby dojść na końcu (wszak to c-string), a tu miejsca brak
Jeśli już, to tak:
- Kod: Zaznacz cały
char * Buf = new char[255];
ale zaraz zaraz, po co w ogóle alokować, przecież można tak:
- Kod: Zaznacz cały
char Buf[255];
co ciekawe taką deklarację zrobiłeś w następnych przykładach. I to jest poprawna forma, ale w stylu C. W C++ powinno to wyglądać tak:
- Kod: Zaznacz cały
string text;
...
infile >> text;
getline(infile,text); //<--- czytanie całej linii.
Jest to wersja bezpieczna.
gdyż funkcja IsEmpty sprawdza, czy łańcuch znaków jest pusty, czyli nie przetwarza całego łańcucha.
Oczywiście, że przetwarza, bo zapis:
- Kod: Zaznacz cały
((AnsiString)Buf)
to nic innego jak:
- Kod: Zaznacz cały
AnsiString(Buf) //<--- wywołanie ctor'a __fastcall AnsiString::AnsiString(const char* src);
Czyli, żeby
Empty zadziałało
AnsiString musi zostać zainicjowany c-stringiem - czyli skonstruowany. A tu wiadomo:
strlen, alokacja, kopiowanie - to trochę trwa (na pewno dłużej niż dostęp do pierwszego znaku w
Buf)
Jeśli nie wierzysz, ustaw breakpointa na tym wyrażeniu, przejdź na widok CPU i zobaczysz, że pierwsza funkcja (
call), która zostanie wywołana to konstruktor
AnsiStringa, dopiero później będzie to
Empty.