2012-06-03 2 views
1

Lorsque j'imprime un pointeur char avec printf(), il prend la décision avec spécificateur de conversion si l'adresse doit être imprimée ou la chaîne entière en fonction de% u ou% s.pointeur char confondant avec cout en C++

Mais quand je veux faire la même chose avec cout, comment va cout décider ce qui devrait être imprimé parmi l'adresse et la chaîne entière? Voici une source d'exemple:

int main() 
{ 
    char ch='a'; 
    char *cptr=&ch; 
    cout<<cptr<<endl; 
    return 0; 
} 

Ici, dans mon compilateur GNU, cout tente de sortie ch comme une chaîne. Comment puis-je obtenir l'adresse ch via cptr en utilisant cout?

+0

Copie possible de l'argument [cout << avec l'argument char \ * imprime la chaîne, pas la valeur du pointeur] (http://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer -valeur) – GingerPlusPlus

Répondre

12

La résolution de surcharge sélectionne le ostream& operator<<(ostream& o, const char *c); qui est utilisé pour l'impression de chaînes de style C. Vous voulez que l'autre ostream& operator<<(ostream& o, const void *p); soit sélectionné. Vous êtes probablement mieux avec une distribution ici:

cout << static_cast<void *>(cptr) << endl; 
+0

'static_cast ' devrait suffire dans ce cas, puisque nous parlons de pointeur de type de données de base. – Zeta

+0

@Zeta: Yup. Édité. – dirkgently

7

cout imprime une chaîne si elle reçoit un char *, simple comme cela.

Voici les operator << pour pour les surcharges ostream:

ostream& operator<< (bool val); 
ostream& operator<< (short val); 
ostream& operator<< (unsigned short val); 
ostream& operator<< (int val); 
ostream& operator<< (unsigned int val); 
ostream& operator<< (long val); 
ostream& operator<< (unsigned long val); 
ostream& operator<< (float val); 
ostream& operator<< (double val); 
ostream& operator<< (long double val); 
ostream& operator<< (const void* val); 

ostream& operator<< (streambuf* sb); 

ostream& operator<< (ostream& (*pf)(ostream&)); 
ostream& operator<< (ios& (*pf)(ios&)); 
ostream& operator<< (ios_base& (*pf)(ios_base&)); 

ostream& operator<< (ostream& out, char c); 
ostream& operator<< (ostream& out, signed char c); 
ostream& operator<< (ostream& out, unsigned char c); 


//this is called 
ostream& operator<< (ostream& out, const char* s); 
ostream& operator<< (ostream& out, const signed char* s); 
ostream& operator<< (ostream& out, const unsigned char* s); 

Si vous voulez l'adresse, vous voulez:

ostream& operator<< (const void* val); 

si vous avez besoin de jeter à const void*.

+0

merci pour ces détails ... :) c'est très utile .. –

4

Je voudrais juste jeter un vide * il ne cherche pas à l'interpréter comme une chaîne C:

cout << (void*) cptr << endl; 

Cependant, une option plus sûre serait d'utiliser static_cast comme dans la réponse de dirkgently (de cette façon, la distribution est au moins vérifiée au moment de la compilation).

+1

fonte de style c? ne serait-il pas plus sûr d'utiliser un casting C++? –

+0

@AdrienPlisson C'est moins sûr que les distributions en C++ autres que reinterpret_cast. Dans un cas aussi trivial que celui-là, je ne m'embêterais pas avec un casting de style C++, bien que je suppose que pour être complet, je devrais le mentionner. Il est difficile de prévoir une situation dans laquelle une distribution serait nulle, juste pour que cela devienne nuisible, même si je suis sûr qu'une fois qu'une base de code sera suffisamment grande, des coulées vraiment étranges pourraient se produire. – Corbin

+0

@Corbin: Pour 'void *', 'reinterpret_cast' de C++ 11 est juste correct. Voir [le numéro 1120] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1120). – dirkgently

0

Comme dit Luchian, cout sait quoi imprimer en fonction du type. Si vous voulez imprimer la valeur du pointeur, vous devez placer le pointeur sur void * qui sera interpolé comme un pointeur.