2011-09-23 3 views
1

J'ai un problème que je ne comprends pas. J'ajoute des caractères à une chaîne standard. Quand je les sors, la valeur imprimée n'est pas ce à quoi je m'attendais.Comportement de chaîne standard avec des caractères en C++

int main (int argc, char *argv[]) 
{ 
    string x; 
    unsigned char y = 0x89, z = 0x76; 
    x += y; 
    x += z; 
    cout << hex << (int) x[0] << " " <<(int) x[1]<< endl; 
} 

La sortie: ffffff89 76

Ce que je pensais: 89 76

Toutes les idées que ce qui se passe ici? Et comment puis-je résoudre ce problème?

+1

Alors, à quoi vous attendriez-vous? – Howard

+0

où est défini 'z'? OK je le vois maintenant dans l'édition. – danishgoel

+0

N'utilisez jamais de lancers implicites! – KillianDS

Répondre

1

Vous devez tenir compte du fait que char peut être signé. Si vous le promouvez directement à int, la valeur signée sera conservée. Au lieu de cela, vous devez d'abord le convertir en un type non signé de la même largeur (unsigned char) pour obtenir la valeur souhaitée et puis pour promouvoir cette valeur en un type entier afin d'obtenir l'impression formatée correcte.

Mettre le tout ensemble, vous voulez quelque chose comme ceci:

std::cout << (int)(unsigned char)(x[0]); 

Ou, en utilisant le C++ - coulé style:

std::cout << static_cast<int>(static_cast<unsigned char>(x[0])) 
4

L'opérateur de chaîne [] génère un char, c'est-à-dire une valeur signée. Lorsque vous convertissez ceci en int pour la sortie, ce sera également une valeur signée.

La valeur d'entrée attribuée à un char est négative et le int le sera également. Ainsi, vous voyez la sortie que vous avez décrite.

+2

Rappelez-vous que 'char' est' signed' ou 'unsigned' est défini par l'implémentation. –

+0

+1: Mais si le type de caractère par défaut est signé ou non dépend de l'implémentation – 6502

+0

c'est ce que je pensais aussi. Et je viens de le tester et c'est le cas "0x79" sort correctement, mais ensuite c'est le 'ffffffxx'. – danishgoel

2

Très probablement char est signed sur votre plate-forme, donc 0x89 et 0x76 deviennent négatifs quand il est représenté par char.

Vous avez à vous assurer que la chaîne a unsigned char comme value_type, donc cela devrait fonctionner:

typedef basic_string<unsigned char> ustring; //string of unsigned char! 

ustring ux; 
ux += y; 
ux += z; 
cout << hex << (int) ux[0] << " " <<(int) ux[1]<< endl; 

Il imprime ce que vous pensez devrait imprimer:

89 76 

Démo en ligne: http://www.ideone.com/HLvcv

+0

'0x76' ne devrait pas (et ne devient pas) négatif. –

+0

Aussi (bien que cela ne soit pas pertinent pour votre propos), 'basic_string ' est un comportement indéfini. Un grand nombre d'implémentations (VC++ et g ++, au moins) le définissent, mais pas nécessairement de la même manière. –

+0

@JamesKanze: Pourquoi 'basic_string ' est un comportement indéfini? – Nawaz

0

Le nombre 0x89 est 137 dans le système décimal. Il dépasse the cap of 127 et est maintenant un nombre négatif et donc vous voyez ces ffffff là. Vous pouvez simplement simplement insert (unsigned char) after the (int) cast. Vous obtiendriez le résultat requis.

-Sandip

Questions connexes