2009-02-02 4 views
-1

Alors ... quand je vais:Pourquoi c_str() imprime-t-il deux fois la chaîne?

cout<<stringName<<endl; 

je reçois:

NT 

Mais quand je vais:

cout<<stringName.c_str()<<endl; 

Je reçois:

NTNT 

Pourquoi?

+0

Utilisez-vous wstring par hasard. –

+0

Je ne sais même pas ce que c'est. – Alex

+0

Faites-vous des fork() à proximité - peut-être que vous avez plusieurs processus de vidage des tampons plus ou moins même. –

Répondre

9

Un test rapide avec le code suivant:

#include <string> 
#include <iostream> 

using namespace std; 

int main(void) { 
    string str = "NT"; 
    cout << str.c_str() << endl; 
    return 0; 
} 

produit une instance de NT il semble que vous avez probablement un autre appel de sortie quelque part.

+0

Comment cela pourrait-il être la cause? En supposant qu'il a simplement changé cette ligne de 'stringName' à 'stringName.c_str()', cela ne peut pas changer le nombre de fois que la chaîne est imprimée. De plus, il imprime une nouvelle ligne, donc ce n'est clairement pas deux instances de ce code en cours d'exécution. –

+0

@Larry Il n'y a aucune indication de ce que le reste du code ressemble ou que la même entrée a été utilisée entre les exécutions de sorte qu'il pourrait être dans une condition quelque part. Il n'y a également aucune garantie qu'un appel précédent inclurait une endl non plus. J'ai dit "probablement" pour une raison. –

+0

@Kevin S'il y a "un autre appel de sortie", cela arrive en premier et n'a pas de saut de ligne. Je prenais à la valeur nominale que la seule chose qu'il a changé était cette ligne, pas "l'autre". Dans les deux cas, le comportement CHANGE de la manière décrite n'est pas expliqué simplement par la présence d'une autre commande d'impression "NT". –

1

Ce n'est pas un problème avec c_str(), mais probablement lié à une autre anomalie dans le reste du programme. Créez une application "hello world" qui effectue ces mêmes opérations et vous verrez que cela fonctionne très bien là-bas.

2

Afficher plus de code. Il semble que vous avez fait cout << ealier et j'ai oublié que vous l'avez fait. Qu'est-ce qu'il imprime si vous faites cout<< "mofo" << stringName.c_str()<< "|||" << endl; Est-ce que ça dit NTmofoNT|||? si oui qui pourrait bien être ce qui est arrivé;)

4

Une chaîne traditionnelle C (accessible par un char const*) a une séquence de caractères terminée par un caractère 0. (pas le chiffre 0, mais une valeur nulle réelle, que nous écrivons '\0'.) Il n'y a pas de longueur explicite — donc diverses opérations de chaîne lisent juste un caractère à la fois jusqu'à ce qu'il frappe le '\0'.

Un C++ std::string a une longueur explicite dans sa structure.

Est-il possible que la mise en mémoire des caractères de votre chaîne ressemble à ceci:

'NTNT\0' 

, mais la longueur de la chaîne est réglée sur 2?

qui résulterait exactement ce comportement — manipuler le std::string va directement agir comme il est juste deux caractères, mais si vous faites des opérations traditionnelles C en utilisant s.c_str(), il ressemblera "NTNT".

Je ne suis pas sûr de ce que les manigances pourraient vous amener dans cet état, mais il serait certainement correspondre aux symptômes.

Une façon vous pourriez entrer dans cet état serait en fait écrire aux caractères de la chaîne, quelque chose comme: strcat((char *)s.c_str(), "NT")

+0

Vous obtiendriez ce comportement seulement si std :: string :: c_str() est défectueux. c_str() est garanti par la norme (21.3.6 [1]) pour pointer vers un tableau (pas nécessairement le même stockage que la chaîne utilise en interne) terminé par un @ 0 –

+0

@Steve, pas si c_str() ne le fait pas quoi que ce soit et les données sont déjà maintenues de manière nulle. Ensuite, si vous écrasez ce terminateur null en le manipulant directement avec data(), il pourrait avoir ce résultat. –

+0

Et en général, si vous avez fait quelque chose d'invalide à l'objet chaîne et le résultat est que c_str() ne fait pas ce que vous attendez, cela ne signifie pas que c_str() est défectueux ;-) –

Questions connexes