2009-05-07 20 views
16

¿Cómo se determina la longitud de un char * sin signo?¿Cómo se determina la longitud de un char * sin signo?

+2

La mayoría de las respuestas indican la necesidad de especificar el significado de "longitud": número de elementos, tamaño de la variable que contiene el puntero o puede estar refiriéndose a los caracteres (¿sin signo?) Una cadena terminada en cero? – xtofl

Respuesta

21

Para el tamaño real del puntero:

size_t s = sizeof(unsigned char*); 

Si desea que la longitud de la cadena:

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

"blabla" produce una cadena de solo lectura, por lo que bla debe ser const unsigned char *. –

+2

Esto no debería compilarse. "blabla" es un const char *, y no se puede asignar un const char * a un char * sin signo sin conversión. –

+0

Eso no es tarea, es inicialización, todo el tiempo. –

-3

Por unsigned char * supongo que te refieres a la cadena situada en ese puntero. En ese caso sería:

strlen(your_string_pointer) 

Sin embargo, esto solo encontrará la posición \ 0. No hay garantía de que este sea el tamaño real del bloque de memoria asignada.

+0

http: //www.cplusplus.com/reference/clibrary/cstring/strlen ... strlen toma un "const char *", no un unsigned. – xtofl

8

Puede haber dos significados para esto. ¿Solo quieres saber qué tan grande es el tipo de puntero? Si es así, la respuesta de Joce es correcta

size_t size = sizeof(unsigned char*); 

Si estás queriendo saber cuántos elementos hace el punto puntero a, eso es un poco más compleja. Si esta es una cadena de estilo C, strlen o alguna variante es tu mejor opción.

Sin embargo, si esto es solo un puntero a char sin signo que no tiene relación con una cadena de estilo C, entonces no hay manera de lograr lo que está buscando confiablemente. C/C++ no asocia un campo de longitud con un puntero. Tendrá que pasar el largo con el puntero o usar un vector de clase que almacena tanto el puntero como la longitud.

+1

Tiene razón acerca de no poder recuperar la longitud asignada, una decisión de diseño de lenguaje malo a los ojos de muchas personas. Te equivocas sobre la existencia de dos significados: puede ser que necesites saber la longitud de la cadena con terminación cero contenida, aunque sería mejor usar un carácter firmado. Que sea dos y medio :) – xtofl

0

¿Desea la longitud del puntero, que sería un int. Si desea la longitud de la cadena a la que apunta, use strlen: p. Tamaño del puntero: sizeof (unsigned char *) tamaño de la cadena: strlen (sin firmar char *) caracteres de varios bytes conseguirá reportado como ..multi bytes

+1

En realidad, sería un size_t – Tom

+0

Derecha. Debería haber dicho size_t – Rohit

0

Si está utilizando C++, y su una cadena en un char * sin firmar, es mejor que primero lo pongas en una std :: cadena antes de manipularlo. De esta forma, puede hacer todo tipo de cosas y aún así obtener la longitud() y/o la capacidad() de ella siempre que lo desee.

Supongo que está haciendo cosas en dicha matriz para hacer que su tamaño no sea constante. Si solo está asignando, configurando y olvidando, siempre puede almacenar el tamaño de asignación real de la matriz en una variable separada, o mejor, hacer una estructura/clase.

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

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

Cualquiera más complejo que eso y está reinventando std :: string.

6

En un mundo ideal, no es así. Usas char * para cadenas tipo C (que tienen terminación NUL y puedes medir la longitud de), y char * sin firmar solo para datos de bytes (que viene con su longitud en otro parámetro o lo que sea, y que probablemente entres en un contenedor STL lo antes posible, como vector<unsigned char> o basic_string<unsigned char>).

El problema de raíz es que no puede hacer suposiciones portátiles acerca de si las representaciones de almacenamiento de char y char sin signo son las mismas. Usualmente lo son, pero se les permite no serlo. Por lo tanto, no hay funciones de biblioteca similares a cadenas que operen en char * sin signo, solo en char *, y no es seguro en general lanzar char * sin signo a char * firmado y tratar el resultado como una cadena. Como Char puede estar firmado, esto significa que no se deben enviar caracteres sin signo * a char *.

Sin embargo, 0 siempre es la misma representación de valor en caracteres sin signo y caracteres. Entonces, en un mundo no ideal, si tienes una cadena estilo C de algún lado pero ha llegado como una char * sin signo, entonces (a) la conviertes en char * y sigues con ella, pero también (b)) averigua quién te hizo esto y pídeles que se detengan.

Cuestiones relacionadas