0
votes

Renvoie la chaîne convertie complète en majuscules / minuscules

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;
}

c++

6 commentaires

' ' 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::string pour é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, outWord n'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 outWord donc l'impression qu'il donne un comportement indéfini. Essayez d'utiliser les fonctions standard (dans <cctype> nommées isupper() (pour tester si les majuscules), islower() , toupper() (pour convertir en majuscules) et tolower() .


3 Réponses :


2
votes

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;
}


0 commentaires

1
votes

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];
}


0 commentaires

0
votes

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:

  • Vous pouvez définir j dans la boucle for si vous n'utilisez pas l'int en dehors de la boucle for (int j = 0; j < strlen(inWord); j++){}
  • 'a' - 'A' et 'A' - 'a'
    ont la même valeur absolue et ne changent pas pendant la boucle, vous pouvez donc définir une variable avant la boucle, puis ajouter ou soustraire respectivement l'intérieur de la boucle.

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


0 commentaires