J'écris un programme pour convertir toutes les lettres minuscules d'une chaîne en lettres majuscules, vice versa. Cependant, j'ai trouvé que mon programme ne peut pas renvoyer toute la chaîne convertie.
Voici les résultats et mon code de programme.
Entrée: "une enquête", sortie: "A".
Entrée: "Bonjour", Sortie: "bonjour".
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char inWord[50], outWord[50];
int j = 0;
cin.getline(inWord, 50);
for (j = 0; j < strlen(inWord); j++)
{
//upper to lower
if (inWord[j]>='A'&&inWord[j]<='Z')
outWord[j] = inWord[j] + 'a' - 'A';
//lower to upper
else
outWord[j] = inWord[j] + 'A' - 'a';
}
cout << outWord;
return 0;
}
3 Réponses :
Vous devez prendre en compte les caractères qui ne sont pas des lettres. Vous convertissez maintenant l'espace en 0, ce qui signifie que cout sait qu'il doit arrêter la lecture de la chaîne. C'est une solution simple:
#include <iostream>
#include <string>
int main() {
std::string inWord, outWord;
std::getline(std::cin, inWord);
outWord.reserve(inWord.size());
for (int i = 0; i < inWord.size(); i++)
{
char c = inWord[i];
//upper to lower
if (c>='A' && c<='Z') {
outWord.push_back(c + 'a' - 'A');
}
//lower to upper
else if (c>='a' && c<='z') {
outWord.push_back(c + 'A' - 'a');
}
else {
outWord.push_back(c);
}
}
std::cout << outWord;
return 0;
}
Et si vous programmez en C ++, vous devriez probablement remplacer ces char [50] par std :: string, et éviter d'utiliser l'espace de noms std:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char inWord[50], outWord[50];
cin.getline(inWord, 50);
for (int j = 0; j < strlen(inWord); j++)
{
char c = inWord[j];
//upper to lower
if (c>='A' && c<='Z')
outWord[j] = c + 'a' - 'A';
//lower to upper
else if (c>='a' && c<='z')
outWord[j] = c + 'A' - 'a';
else
outWord[j] = c;
}
cout << outWord;
return 0;
}
En ascii,
' ' n'est pas dans 'A' plage 'A' - 'Z' , donc la deuxième branche est prise. Par hasard, sa valeur est 'a' - 'A' . résultant en '\0' (terminateur nul de la chaîne C).
Pour résoudre ce problème, vous devez gérer un troisième cas:
const std::size_t size = strlen(inWord)
for (std::size_t j = 0; j < size; j++)
{
unsigned char c = static_cast<unsigned char>(inWord[j]);
if (std::isupper(c))
outWord[j] = static_cast<char>(std::tolower(c));
//lower to upper
else if (std::islower(c))
outWord[j] = static_cast<char>(std::toupper(c));
else
outWord[j] = inWord[j];
}
'a' - 'z' , 'A' - 'Z' ne sont pas garantis comme étant des plages contiguës (c'est pour Ascii, pas pour EBCDIC), vous pouvez donc utiliser des méthodes standard à la place (même si leurs interfaces sont sujettes aux erreurs :( ):
const std::size_t size = strlen(inWord)
for (std::size_t j = 0; j < size; j++)
{
//upper to lower
if (inWord[j]>='A'&&inWord[j]<='Z')
outWord[j] = inWord[j] + 'a' - 'A';
//lower to upper
else if (inWord[j]>='a'&&inWord[j]<='z')
outWord[j] = inWord[j] + 'A' - 'a';
else
outWord[j] = inWord[j];
}
Si vous souhaitez convertir toutes les lettres, par exemple, dans le cas contraire, vous devez vérifier dans quelle cas la chaîne se trouve après l'entrée. (par exemple en comptant les caractères majuscules).
En ce moment, vous inversez la casse de chaque lettre, tout en effectuant une comparaison if else de chaque lettre de la boucle. Si vous exécutez une seule des 2 conditions de branchement, il effectuera une conversion dans le même cas.
Quelques mots sur la façon dont vous pourriez souhaiter améliorer votre style:
for (int j = 0; j < strlen(inWord); j++){}Il est également utile de savoir que C ++ traite les caractères comme des nombres 8 bits dans le cas de l'ascii, c'est la raison pour laquelle le calcul de décalage fonctionne: Lien vers une table ASCII
' 'n'est pas dans'A'-'Z'plage'A'-'Z'et par danger, c'est'a' - 'A'.ne confondez pas "retour d'une fonction" et "impression vers la console", c'est évident ce que vous entendez ici, mais en général ces deux sont complètement différents et sans rapport
Veuillez utiliser
std::stringpour éviter un tas de problèmes.outword [j] n'est pas défini (0) si inword ne fait pas partie de [a-zA-Z]. L'espace fait en sorte que la valeur par défaut 0 pour ce caractère reste, qui est le terminateur nul indiquant que la fin de la chaîne est atteinte à cout.
En plus des problèmes ci-dessus,
outWordn'est pas terminé par nul , ce qui est une exigence pour une chaîne C.Tous les jeux de caractères standard n'ont pas les jeux de lettres majuscules et minuscules sous forme de jeu contigu, et votre code suppose qu'ils le font. Votre code essaie également de convertir tout caractère non alphabétique, tel que les espaces, en majuscules, ce qui ne produira même pas nécessairement (selon le jeu de caractères) un caractère imprimable. Il n'écrit pas non plus un nul de fin dans
outWorddonc l'impression qu'il donne un comportement indéfini. Essayez d'utiliser les fonctions standard (dans<cctype>nomméesisupper()(pour tester si les majuscules),islower(),toupper()(pour convertir en majuscules) ettolower().