En C11, se ha agregado un nuevo literal de cadena con el prefijo u8. Esto devuelve una matriz de caracteres con el texto codificado para UTF-8. Como es esto posible? ¿No está firmado un char normal? ¿Quiere decir que tiene un poco menos de información para usar debido al bit de signo? Mi lógica mostraría que una cadena de texto UTF-8 necesitaría ser una matriz de caracteres sin signo.¿Cómo puede char [] representar una cadena UTF-8?
Respuesta
¿No es un chantaje normal firmado?
Es dependiente de la implementación si char
es signed
o unsigned
.
Además, el bit de signo no se "pierde", todavía se puede usar para representar información, y char
no es necesariamente de 8 bits (puede ser mayor en algunas plataformas).
* "también puede estar sin firmar" * ... pero no al mismo tiempo :-) –
El estándar dice 'char' siempre tiene 1 byte de longitud. Sin embargo, el tamaño de un byte puede variar. Use 'CHAR_BIT' (de' limits.h') para conocer el tamaño real de 1 byte. – jweyrich
No, un bit de signo es un poco no obstante! Y la especificación UTF-8 en sí misma no dice que los caracteres deben estar sin firmar.
PS Wat es kookwekker voor 'n naam?
Hay un problema potencial aquí:
Si una implementación con CHAR_BIT == 8
utiliza firmar grados de magnitud representación de char
(por lo char
se firma), entonces cuando UTF-8 requiere que el patrón de bits 10000000
, que es una negativo 0. Entonces, si la implementación no admite 0 negativo, entonces una cadena UTF-8 dada podría contener un valor inválido (trap) de char
, lo cual es problemático. Incluso si admite cero negativo, el hecho de que el patrón de bits 10000000
se compare igual que char
con el patrón de bits 00000000
(el terminador nul) es probable que cause problemas al utilizar datos UTF-8 en un char[]
.
Creo que esto significa que para las implementaciones C11 de magnitud de señal, char
debe estar sin firmar. Normalmente depende de la implementación si char
está firmado o no, pero por supuesto si char
está siendo firmado resulta en que no se implementan los literales UTF-8 correctamente, entonces el implementador solo tiene que seleccionar unsigned. Como un aparte, este ha sido el caso para las implementaciones de complemento de 2 de C++ todo el tiempo, ya que C++ permite char
así como unsigned char
para ser utilizado para acceder a representaciones de objetos. C solo permite unsigned char
.
En complemento a 2 y el complemento 1s', los patrones de bits necesarios para UTF-8 datos son valores válidos de signed char
, por lo que la aplicación es libre de hacer char
ya sea con o sin signo y aún así ser capaz de representar cadenas UTF-8 en char[]
. Esto se debe a que todos los patrones de 256 bits son valores de complemento de 2 válidos, y UTF-8 no usa el byte 11111111
(complemento negativo de 1s).
Tu publicación utiliza una premisa equivocada, a saber, que las implementaciones serían lo suficientemente tontas como para permitir valores de -0 para los caracteres. Ellos nunca lo son. –
@Mr Lister: No creo que mi respuesta haga ninguna suposición sobre qué implementaciones realmente hacen. Simplemente enumera lo que están (no) autorizados a hacer, y en particular la única representación recientemente descartada por el requisito en C11 para soportar UTF-8. Para todos los propósitos prácticos, cada implementación es un complemento de 2, pero el estándar continúa permitiendo las alternativas (tontas). –
Creo que su publicación es muy perspicaz, pero aquí es donde estoy confundido: el estándar C++ 11 permite que un 'unsigned char' y' char' se usen para aliasing (vea §3.10/15) y C11 incluso permite * all * tipos de caracteres (ver §6.5/7). Para mí, esto significa que estos tipos deben ser capaces de leer un byte de valor '11111111' (o * cualquier * otro valor de byte). En C++ 11, esto puede resolverse haciendo que un simple 'char' sin signo * si el complemento * 2 no se utiliza. Pero en C11 esto no puede resolverse nunca si el complemento 2 * no es * utilizado, porque el aliasing debe funcionar con todos los tipos de caracteres (§6.5/7), es decir, incluso explícitamente ... – JohnCand
La firma de char no importa; utf8 se puede manejar con solo operaciones de desplazamiento y máscara (que pueden ser engorrosas para tipos con signo, pero no imposible) Pero: utf8 necesita al menos 8 bits, por lo que "assert (CHAR_BIT> = 8);"
Para ilustrar por punto: los siguientes fragmentos no contienen operaciones aritméticas en el valor del carácter, solo cambian la máscara &.
static int eat_utf8(unsigned char *str, unsigned len, unsigned *target)
{
unsigned val = 0;
unsigned todo;
if (!len) return 0;
val = str[0];
if ((val & 0x80) == 0x00) { if (target) *target = val; return 1; }
else if ((val & 0xe0) == 0xc0) { val &= 0x1f; todo = 1; }
else if ((val & 0xf0) == 0xe0) { val &= 0x0f; todo = 2; }
else if ((val & 0xf8) == 0xf0) { val &= 0x07; todo = 3; }
else if ((val & 0xfc) == 0xf8) { val &= 0x03; todo = 4; }
else if ((val & 0xfe) == 0xfc) { val &= 0x01; todo = 5; }
else { /* Default (Not in the spec) */
if (target) *target = val;
return -1; }
len--;str++;
if (todo > len) { return -todo; }
for(len=todo;todo--;) {
/* For validity checking we should also
** test if ((*str & 0xc0) == 0x80) here */
val <<= 6;
val |= *str++ & 0x3f;
}
if (target) *target = val;
return 1+ len;
}
Tenga en cuenta que la norma _guarantees_ 'CHAR_BIT' ≥ 8. –
- 1. .NET System :: Cadena a UTF8-bytes almacenada en char *
- 2. Cómo convertir una cadena a UTF8?
- 3. Cómo truncar una cadena UTF8 en PHP?
- 4. En Java, ¿cómo se convierte una Cadena en un char o un char en una Cadena?
- 5. php json_encode utf8 char problema (mysql)
- 6. Representar char como un byte en Java
- 7. Almacenar una cadena como UTF8 en C#
- 8. ¿Convertir cadena latin1 a utf8?
- 9. La cadena no puede cambiar. Pero int, char puede cambiar
- 10. Comportamiento extraño de ruby regex en rieles con utf8 char
- 11. Ejemplo de cadena utf8 no válida?
- 12. Representando una Char con cadena equivalente
- 13. C++: inserte char en una cadena
- 14. Diferencia entre char a [] = "cadena"; char * p = "cadena";
- 15. no se puede convertir de 'cadena' a 'char []' para dividir
- 16. cómo copiar char * en una cadena y viceversa
- 17. ¿Por qué se puede asignar una cadena a un puntero char *, pero no a una matriz char []?
- 18. Convertir cadena a char
- 19. ¿Cuántos bytes toma una cadena? ¿Un char?
- 20. Cadena Unicode eliminar char de la cadena
- 21. Cómo concatenar char y cadena en iPhone?
- 22. ¿Cómo obtener char de cadena por índice?
- 23. Cómo convertir un puntero char * en una cadena C++?
- 24. cómo asignar una cadena a char * pw en C++
- 25. ¿Cómo convierto una cadena en un char * en C++?
- 26. printf pregunta con una variable const char *
- 27. Verificar la cadena utf8 válida en Python
- 28. ¿Cómo puede char * ser una condición en for loop?
- 29. ¿Cómo cambiar 1 char en la cadena?
- 30. Cómo convertir UTF8 a Unicode
UTF-8 representa caracteres que usan más de 8 bits (lo cual siempre me confunde ya que UTF-16 tiene 16 bits). Además, un char es solo un grupo de bits, por lo que tal vez se firme o no solo importa si está pensando en el valor como un número. Si está pensando en que es (parte de) una representación de un símbolo utf-8, no importa si el compilador cree que el área en la memoria representa un número firmado o no firmado. (Esta no es una respuesta, solo cómo mi lógica lo interpreta). – Oliver
@Oliver ¿Cuál es la parte que lo confunde? UTFf-8 es tanto 8 bit como UTF-16 es 16 bit. –
@MrLister Los caracteres UTF-16 ocupan 1 o 2 bytes de memoria. Los caracteres UTF-8 pueden ocupar cualquier número de byes de memoria (generalmente de 1 a 6 bytes). Entonces, en mi opinión, 'UTF-8' sería una codificación de 8 bits tipo ascii. Mientras que el verdadero UTF-8 sería mejor llamado UTF-48, o similar. O al menos, creo que así es como funciona. Nunca entendí las codificaciones de caracteres de ancho variable cuando estaba haciendo C hace un par de años, y ahora trabajo en idiomas más felices donde esto no es realmente una preocupación ... – Oliver