2017-07-11 2 views
0

Pourquoi ce programme n'imprime-t-il pas "bonjour" en marche arrière? Cela fonctionne quand je décommente la ligne à l'intérieur de la boucle. Je veux connaître le concept derrière lequel la valeur de chaîne n'est pas stockée. Je vous remercie!stocker une lettre lettre par lettre et l'imprimer

#include<iostream> 

using namespace std; 

void reverse(string str) { 
     int length = str.length(); 
     int x = length, i = 0; 
     string newString; 

     while(x >= 0) { 
       newString[i] = str[x-1]; 
       //cout << newString[i]; 
       x--; 
       i++; 
     } 

     cout << newString; 
} 

int main() { 
     reverse("hello"); 

return 0; 
} 
+1

le temps d'utiliser un débogueur. Cela devrait vous aider à comprendre ce qui se passe assez rapidement. – aschepler

+0

Jetez un oeil à la page de référence de l'opérateur [] en C++. Il agit comme un getter, pas un setter http://www.cplusplus.com/reference/string/string/operator[]/ –

+1

Je crains que ce n'est pas tout à fait vrai, @Cole. '[]' renvoie une référence lui permettant d'effectuer une double tâche. En supposant que 'string' n'est pas constant, c'est-à-dire. – user4581301

Répondre

5

newString a une taille de 0 (construite avec le constructeur par défaut), de manière à écrire après la fin de celui-ci avec newString[i] = ... provoque un comportement non défini. Utilisez .resize pour redimensionner la chaîne (faites-la assez grande) avant d'y écrire

2

Il y a plusieurs problèmes avec le programme.

Pour commencer, vous devez inclure l'en-tête <string>

#include <string> 

parce que le programme utilise les déclarations de cet en-tête. Il ne faut pas que l'en-tête <iostream> comprend l'en-tête <string>

Il est préférable de déclarer la fonction comme

void reverse(const string &str); 

Sinon, une copie de la chaîne d'origine utilisée comme argument est créé chaque fois que la fonction est appelé.

Pour le type de taille, la classe std::string définit son propre type entier non signé nommé size_type. Il est préférable de l'utiliser ou le spécificateur de type auto au lieu du type int.

Après cette déclaration

string newString; 

newString est vide. Vous ne pouvez donc pas appliquer l'opérateur d'indice. Vous devez redimensionner la chaîne ou réserver suffisamment de mémoire pour les nouveaux éléments ajoutés à la chaîne. En tenant compte de cela, la fonction peut être définie de la manière suivante.

#include <iostream> 
#include <string> 

using namespace std; 

void reverse(const string &str) { 
     auto length = str.length(); 
     string newString; 
     newString.reserve(length); 

     for (auto i = length; i-- != 0; ) newString += str[i]; 

     cout << newString << endl; 
} 

int main() { 
     reverse("hello"); 

     return 0; 
} 

prendre en compte que la fonction pourrait être définie plus simple basée sur les caractéristiques de la classe std::string elle-même. Par exemple

#include <iostream> 
#include <string> 

using namespace std; 

void reverse(const string &str) { 
     string newString(str.rbegin(), str.rend()); 

     cout << newString << endl; 
} 

int main() { 
     reverse("hello"); 

     return 0; 
} 
+0

pourriez-vous m'expliquer le raisonnement derrière l'utilisation de "const string & str" un peu plus s'il vous plaît? Je vous remercie. – aashman

+0

@aashman Il est utilisé une référence à la chaîne d'origine qui n'est pas une copie de la chaîne d'origine est créée tandis que dans votre programme une copie de la chaîne d'origine est créée chaque fois que la fonction est appelée. C'est la ressource consommée. –