À partir du C ++ 0x projet de travail, les nouveaux types de char ( char16_t strong> et char32_t strong>) pour la manipulation Unicode sera non signé ( uint_least16_t strong> et uint_least32_t strong> seront les types sous-jacents). p>
Mais pour autant que je peux voir (pas très loin peut-être) un type char8_t strong> (basé sur uint_least8_t strong>) n'est pas défini. Pourquoi ? p>
Et il est encore plus confus quand vous voyez qu'une nouvelle U8 strong> préfixe codage est introduit pour la chaîne UTF-8 littérale ... basée sur vieil ami (signe / non signé) char strong>. Pourquoi? P>
Mise à jour strong>:
Il y a une proposition visant à ajouter un nouveau type: char8_t p>
char8_t: Un type de caractères UTF-8 et les chaînes (Version 1)
http: //www.open-std. org / JTC1 / SC22 / WG21 / docs / documents / 2018 / p0482r1.html p>
3 Réponses :
UTF-8 ne représente pas les points de code directement, donc il n'a pas d'importance si char16_t code> et
char32_t code> sont censés être utilisables pour représenter les points de code. , Il est judicieux car il n'y a pas de points de code de négatif pour ceux-ci soient non signés. P>
U8 code> type sous-jacent de 'est signé ou non. P>
Si je veux conserver le caractère é (U + 00E9), qui est la séquence de deux octets 0xC3 0xA9, avec un tableau de char signé échouera: signed char e_acute = {} 0xC3,0xA9 => ce tronque la valeur. Donc, si votre système définit char comme signed char, il est toujours un problème. Ai-je tort ?
Très rarement vous devez saisir les octets manuellement: souvent, comme vous dites, U8 code> est utilisé. Donc, les octets élevés Parvenez traités comme des nombres négatifs dans ce cas.
Chris, est-il une garantie que la paire de conversions unsigned char -> signed char -> unsigned char code> donnera la valeur initiale? L'ancienne conversion est définie par l'implémentation et je ne pouvais pas trouver une clause qui garantirait l'aller-retour.
@avakar: Je ne sais pas pourquoi le roundtripping est important dans ce cas (à moins que je mal lu votre commentaire). La façon dont je comprends la tâche est la suivante: vous avez besoin d'un moyen de convertir un tas de char code> dans un tas de
char16_t code> ou
char32_t code>. Vous pouvez facilement élargir un au cours de cette conversion
char code>.
Mon point est que si vous recevez des données UTF-8 de quelque part (comme une séquence de nombres dans la plage de 0 à -255, qui est comment UTF-8 est définie), vous ne pouvez pas les stocker de manière fiable dans un tableau de caractères, car la valeur que vous souhaitez obtenir par moulage retourner à unsigned char code> peut être différent (et je ne suis même pas sûr que
CHAR_BIT code> est assuré d'être au moins 8). Pour la fiabilité, vous devez utiliser
uint_least8_t code>, et pour moi, il semble utile et cohérente pour fournir
char8_t code> typedef pour elle.
Non, vous n'interprétez UTF8 directement. Vous passez à une fonction de support d'exécution qui le convertit en un type de caractères natif, comme wchar_t. Donc, peu importe quel genre de sac d'octets que vous mettez dans.
La lecture d'un fichier UTF-8 dans un char buffer signé produira le même problème. Aussi, si votre personnage est signé, vous ne pouvez pas supposer qu'une std :: string (basic_string
@avakar: Normalement, vous lisez dans les données d'octets à partir d'un fichier ou d'un réseau. Ceux-ci généralement stockés sous forme de char code> déjà, quelle que soit signedness est native du système. Ainsi, dans un cas signé (dans l'exemple de l'OP), 0xC3, 0xA9 est lu comme -0x3D, -0x57 (sur les systèmes de complément de deux). C'est très bien: les fonctions de conversion peuvent promouvoir encore de façon significative que dans un int, et les transformer en points de code réels de cette façon.
char code> 's gamme garantie pourrait être à petit que [-127 .. + 127] si elle est signée et si la mise en œuvre utilise une représentation grandeur signée au lieu de complément à deux. En fait, la plage valide de
char code> peut être aussi petit que [0..127] si votre jeu de caractères hôte est simplement ASCII, même si je pense qu'il doit encore être d'au moins 8 bits. Lecture "octets bruts" dans un tableau de
char code> semble donc théoriquement non-portable. Je l'ai toujours utilisé des tableaux de
unsigned char code> quand je besoin d'un sac d'octets. Ai-je mal compris quelque chose?
Peu importe. J'ai lu que C ++ 0x a a modifié la définition i> de char code> de telle manière à exclure les représentations qui mènent à la [0..127] et [- 127 .. + 127] gammes. Donc, une fois que vous êtes sur un nouveau compilateur conforme, un tableau de
char code> est suffisant pour maintenir un sac d'octets. Jusque-là, cependant,
unsigned char code> est un pari plus sûr.
char sera le type utilisé pour UTF-8 parce qu'il est redéfinie pour être sûr qu'il peut être utilisé avec elle: p>
Aux fins de l'amélioration du soutien pour Unicode dans les compilateurs C, définition du type char a été modifié pour être à la fois au moins la taille nécessaire pour stocker un codage de huit bits de UTF-8 et assez grand pour contenir tout membre du compilateur de base est caractères d'exécution strong>. C'était précédemment défini comme seul ce dernier. Il y a trois encodages Unicode C ++ 0x soutiendra: UTF-8, UTF-16, et UTF-32. En plus de l'avant changements notés à la définition de char, C ++ 0x ajoutera deux nouveaux caractères types: char16_t et char32_t. Ces sont conçus pour stocker UTF-16 et UTF-32 respectivement. P> blockQuote>
Source: http://en.wikipedia.org/wiki/C%2B % 2B0x p>
La plupart des utilisations d'application UTF-8 car déjà de toute façon sur PC / Mac. P>
Ne dit pas un mot de signedness.
Pourquoi le phrasé maladroit de la partie en gras? N'est pas « codage UTF-8 huit bits » redondant?
Eh bien c'est wikipedia, le libellé change souvent et peut grandement variate qualité. Cependant, je ne l'ai pas trouvé une autre source qui résument les caractéristiques liées unicode.
Le projet de C ++ 0x ne semble pas indiquer si oui ou non les nouveaux types de caractères Unicode sont signés ou non signés. Cependant, comme d'autres l'ont déjà dit, car il n'y a pas de négatif Unicode codepoints il serait plus logique En outre, depuis UTF-16 gammes de 0x0 par 0xFFFF (en ignorant les paires de substitution), vous auriez besoin toute la gamme d'un nombre entier de 16 bits non signé pour représenter correctement toutes les valeurs. Il serait maladroit, pour le moins, si codepoints 0x8000 par 0xFFFF étaient représentés comme des nombres négatifs avec Quoi qu'il en soit, jusqu'à ce que le comité C ++ 0x dit quelque chose de définitif en la matière, vous pouvez toujours vérifier votre implémentation: p> char16_t code> et
char32_t code> non signé. (Là encore, il aurait été logique
char code> non signé, mais nous avons eu affaire à des caractères « négatifs » depuis les années 70.)
char16_t code>. P>
#include <type_traits>
#include <iostream>
int main()
{
std::cout << std::boolalpha << std::is_signed<char16_t>::value << std::endl;
}