2009-05-07 20 views
16

Jak określić długość niepodpisanego znaku *?Jak określić długość niepodpisanego znaku *?

+2

Większość odpowiedzi wskazuje na potrzebę podania przez ciebie wartości "długość": liczba elementów, wielkość zmiennej zawierającej wskaźnik, czy może odnosisz się do znaków (bez znaku?) Do zera zakończonego łańcuchem? – xtofl

Odpowiedz

21

Dla rzeczywistej wielkości wskaźnika:

size_t s = sizeof(unsigned char*); 

Jeśli chcesz długość łańcucha:

unsigned char* bla = (unsigned char*)"blabla"; 
int s = strlen((char*)bla); 
+5

"blabla" daje łańcuch tylko do odczytu, więc bla powinien być stałym znakiem bez znaku *. –

+2

To nie powinno się kompilować. "blabla" to const char * i nie można przypisać znaku const * do znaku bez znaku * bez rzutowania. –

+0

To nie jest zadanie - to inicjalizacja - robione przez cały czas. –

-3

Przez unsigned char * Pewnie myśli ciąg znajdujący się na tym wskaźniku. W takim przypadku byłby to:

strlen(your_string_pointer) 

Jednak tylko znajdzie się pozycja \ 0. Nie ma gwarancji, że jest to faktycznie przydzielony rozmiar bloku pamięci.

+0

http: //www.cplusplus.com/reference/clibrary/cstring/strlen ... strlen pobiera "const char *", a nie bez znaku. – xtofl

8

Może to mieć dwa znaczenia. Czy chcesz wiedzieć, jak duży jest typ wskaźnika? Jeśli tak, to odpowiedź jest poprawna Joce

size_t size = sizeof(unsigned char*); 

Jeśli chce wiedzieć ile elementów ma wskaźnik do punktu, który jest nieco bardziej skomplikowana. Jeśli jest to ciąg w stylu C, to najlepszym rozwiązaniem jest strlen lub jakaś odmiana.

Jednak jeśli jest to tylko wskaźnik do znaku unsigned char, który nie ma związku z łańcuchem w stylu C, to nie ma sposobu, aby niezawodnie osiągnąć to, czego szukasz. C/C++ nie kojarzy pola długości ze wskaźnikiem. Będziesz musiał podać długość za pomocą wskaźnika lub użyć wektora podobnego do klasy, który przechowuje zarówno wskaźnik, jak i długość.

+1

Masz rację, że nie możesz odzyskać przydzielonej długości - w oczach wielu ludzi jest to decyzja dotycząca złych wzorców językowych. Mylisz się, jeśli masz dwa znaczenia: być może musisz znać długość zawartego łańcucha zakończonego zerem, choć lepiej byłoby użyć podpisanego znaku. Zróbcie dwa i pół :) – xtofl

0

Czy chcesz długość wskaźnika, który byłby int. Jeśli chcesz długość łańcucha, który jest wskazywany, użyj strlen: np. Rozmiar wskaźnika: sizeof (unsigned char *) Rozmiar łańcucha: strlen (unsigned char *) znaki wielobajtowe dostanie zgłaszane jako ..multi bajt

+1

Właściwie to byłby to size_t – Tom

+0

Dobrze. Powinienem był powiedzieć size_t – Rohit

0

Jeśli używasz C++, a jego ciąg w unsigned char *, lepiej jest najpierw umieścić go w std :: string przed manipulowaniem nim. W ten sposób możesz robić różne rzeczy i nadal być w stanie uzyskać długość() i/lub pojemność(), kiedy tylko chcesz.

Zakładam, że robisz rzeczy na rzecz wspomnianej macierzy, aby jej wielkość nie była stała. Jeśli tylko alokujesz, ustawiasz i zapominasz, zawsze możesz zapisać rzeczywisty rozmiar alokacji tablicy w oddzielnej zmiennej - lub lepiej, utwórz strukturę/klasę.

//WARNING: memory issues not addressed here. 
struct myStringStruct 
{ 
    unsigned char * string; 
    int len; 

    allocate(int size) { 
    len = size; 
    string = malloc(sizeof(unsigned char) * len); 
    } 
} 

Dosyć bardziej skomplikowany niż to, a Ty ponownie wynajdujesz std :: string.

6

W idealnym świecie nie. Używasz char * dla ciągów w stylu C (które są zakończone NUL i możesz zmierzyć długość), a unsigned char * tylko dla danych bajtowych (które pochodzą z jego długości w innym parametrze lub czymkolwiek, i które prawdopodobnie dostaniesz do pojemnik STL jak najszybciej, taki jak vector<unsigned char> lub basic_string<unsigned char>).

Problemem root jest to, że nie można tworzyć przenośnych założeń o tym, czy reprezentacje pamięci char i unsigned char są takie same. Zwykle są, ale wolno im nie być. Tak więc nie ma funkcji biblioteczkowych podobnych do łańcuchów, które działają na niepodpisanym char *, tylko na char *, a generalnie nie jest bezpiecznie rzucać unsigned char * do podpisanego znaku * i traktować wynik jako ciąg znaków. Ponieważ znak char może być podpisany, oznacza to, że nie ma rzucania niepodpisanego znaku * na znak *.

Jednak 0 jest zawsze tą samą wartością reprezentacji w znaku bez znaku i znaku. Więc w świecie nieidealnym, jeśli masz gdzieś ciąg znaków w stylu C, ale przybył jako niepodpisany znak *, to (a) rzucisz go na znak * i zaczniesz go używać, ale także (b) dowiedz się, kto ci to zrobił i poproś, aby przestali.

Powiązane problemy