8
votes

Comment S [I] ^ = 32 convert la tige en minuscule?

int main()
{
    string s;
    cout << "enter the string :" << endl;
    cin >> s;
    for (int i = 0; i < s.length(); i++)
        s[i] ^= 32;
    cout << "modified string is : " << s << endl;
    return 0;
}
I saw this code which converts uppercase to lowercase on stackoverflow.But I don't understand the line s[i] = s[i]^32.How does it work?

13 commentaires

en.wikipedia.org/wiki/exclusive_or


Ne vous inquiétez pas de ne pas comprendre cela. Il n'est pas portable et ne doit pas être utilisé.


Même pour ASCII SEULÉ SEULEMENT, IT PLUS TOGGLES CASE ET MAUVAIS DES PARTICULIERS AUTRE QUE L'ALPHABETIQUE.


ascitable.com/index/ascifull.gif Voici un coup d'oeil à la table ASCII. A VALUE IN DEC est 97, A VALUE IN DEC est 65. La différence est 32.


@Nathanoliver "Il n'est pas portable" est un peu exagéré - cela fonctionne pour les lettres ASCII A-Z, et de nombreuses applications sont une limitation acceptable. Si vous avez rencontré ce code que quelqu'un d'autre a écrit, ne vous vous une explication de ce que cela fait?


@MarkRansom Bien sûr, si vous savez que votre cas d'utilisation ne sera qu'Acci, ce n'est pas un problème, mais qui devrait être documenté dans le code. Vous devez documenter lorsque vous placez une limite sur les cas où quelque chose fonctionnera lorsque la norme C ++ ne passe aucune limite. De plus, je ne pense pas qu'il y ait une exagération dans ma déclaration. C ++ n'a même pas besoin d'ASCII à utiliser ou que les caractères sont séquentiels.


C'est juste une astuce de code trop "intelligente" qui sacrifie une petite portabilité pour ne rien accomplir. C'est un très mauvais compromis.


@Nathanoliver, je n'ai pas dit que vous étiez mal , bien sûr, la norme ne prévoit pas ASCII. Mais quand est la dernière fois que vous avez utilisé un système qui ne l'a pas fait? Et si je travaillais avec une chaîne qui était déjà garantie de caractères ASCII majuscule, je ne voudrais certainement pas ajouter de documentation supplémentaire pour cette ligne de code, ce serait simplement du bruit. Je suis certainement d'accord sur le fait qu'il existe de meilleures méthodes disponibles.


@Christianhackl dans les olden jours, ce type de code était commun. Il est utile de savoir pourquoi cela fonctionne, car cela vous informera quand ce n'est pas le cas.


@MarkRansom: Bien sûr, la connaissance ne peut pas blesser. Néanmoins, beaucoup de choses étaient différentes dans les jours olden, pas tous pour le mieux.


@MarkRansom dans le olden jours Nous avions Connectes de poinçon autour de: P (et même EBCDIC était autour avant ASCII IIRC)


Plzz me donne un exemple c'est comment je peux le comprendre facilement


Donc, TUPPER () est une seule ligne car tout ce dont il a besoin de rendre compte est ASCII? !!! Bien sûr que non. Vous n'utilisez pas ASCII, vous utilisez ISO-8859-1 ou autre chose. Qu'est-ce que ce code a trait à ÿ et ß?


3 Réponses :


20
votes

12 commentaires

Le code comme celui-ci ne devrait jamais être utilisé.


Cela ne fonctionne que avec des lettres du code ASCII. Essayez-le avec d'autres symboles.


Et cela ne fonctionne bien qu'avec des caractères alphabétiques. Cela fera des choses folles aux autres.


@ Magic-sudo: Il y a beaucoup de caractères ASCII à part A-Z et A-Z.


Cela entraînera probablement du mal à tracer des bugs plus tard.


Vous devriez préciser que les lettres minuscules et majuscules sont 32 positions d'une part seulement si ASCII ou quelque chose de compatible est utilisée et que la norme C ++ ne garantit pas cela.


@Christianhackl J'ai écrit que cela ne fonctionne que avec ASCII, mais n'a pas mentionné la norme car elle ne parle pas du tout de codages de caractères.


@alain: Eh bien, c'est mon point. Vous parlez des 32 positions avant d'indiquer que ASCII ne peut pas être supposé. Ce qui, à un débutant, peut sembler si la déclaration "Les lettres inférieures et majuscules sont 32 positions distantes" est universellement correcte en C ++.


@ EmmanuelMathi-Amorim "Ne jamais être utilisé" est plus utile si vous proposez une alternative.


@alain thx pour les fleurs. J'apprécie votre réponse explique la mécanique sous-jacente.


Plzz me donne un exemple c'est comment je peux le comprendre facilement


@Ashedsami Par exemple, 'A' a le numéro 65. ^ = 32 a pour effet d'ajouter 32 à 65 = 97. 97 est le nombre de 'A'. Vous pouvez lire sur exclusif ou et binaire sur Wikipedia. Passer les pièces d'histoire, commencez à lire lors de «l'informatique» et de «compter en binaire». Ou bien s'il vous plaît dites ce que vous ne comprenez pas exactement.



16
votes

Comment ça marche?

Voyons pour la valeur ASCII 'A' :

'a' est binaire 1000001

xored avec 32 (binaire 100000 )

donne n'importe quelle valeur où le point de caractère supérieur indiquant le bit n'est pas défini:

1000001 < / code> Xor 100000 = 1100001 == 'a' in ascii.


Toute application SANE et portable C ++ doit utiliser tolower () : xxx < / Pré>

Le s [i] = s [i] ^ 32 (Cargo culte) magique, repose sur Table ASCII Mappage spécifique sur numérique Char Valeurs.

Il existe d'autres Char Tables de code comme par exemple ebcdic , où la méthode xxx

ne parvient pas à extraire les lettres minuscules correspondantes.


Il y a une version plus sophistiquée C ++ de la conversion en minuscule Caractères affichés dans la page de documentation de référence de STD :: CTYPE :: Tolower () .


7 commentaires

CTYPE est un modèle de classe, non une classe et tolower () est une fonction de membre non statique.


@Barry thx pour pointer cela. Fixé pour revenir à la version droite C. (Eh bien, cela invalide "Toute application sain et portable C ++" un peu maintenant).


Après tout, ceci est C ++. Pourquoi n'aurais-nous pas trois DIFFÉRENT Fonctions nommée tolower () . Je suppose que si vous comptez la surcharge de la plage du CTYPE un.


Code portable serait s [i] = tolower (((non signé) S [i]) ou s [i] = tolower (S [I], std :: locale () ;


^@m.m a adopté votre 1ère version.


@Ashedsami "Plzz me donne un exemple" Il y a déjà des exemples (vérifiez aussi les liens). Je ne comprends pas ce que vous ne comprenez pas de tout le matériel de référence indiqué dans les réponses à votre question. s [i] = s [i] ^ 32 est une opération exclusive ou Bitwise pour S [i] et 32 . Ceci repose sur la disposition spécifique de la table de caractères ASCII et la relation de caractères majuscules et minuscules commandées.


Toujours pas correct si vous souhaitez que votre programme fonctionne pour un texte non anglais. Les transformations de cas peuvent modifier la longueur d'une chaîne (par exemple, allemand ß majuscule vers ss ) ou être sensible au contexte (par exemple, grec σ inférieur à ς à la fin d'un mot mais σ ailleurs). Cela aurait plus de sens pour C ++ d'avoir des fonctions de boîtier qui fonctionnent sur tout std :: string objets. Avec un argument sur les paramètres régionaux, bien sûr, car il doit faire face au fait que turcs a i / ı et © / i Les paires de cas, contrairement à d'autres langages de script latin utilisant i / i .



5
votes

en C ++, comme son prédécesseur C, un Char est un type numérique. C'est après tout comment les caractères sont représentés sur le matériel et ces langues ne cachent pas cela de votre part.

En ASCII, les lettres ont la propriété utile que la différence entre une lettre majuscule et une lettre minuscule est un seul binaire binaire: le 5ème bit (si nous commençons à la numérotation à partir de la droite à partir de 0).

majuscule a est représenté par l'octet 0b01000001 ( 0x41 en hexagone), et minuscule A est représenté par l'octet 0b01100001 ( 0x61 en hex). Notez que la seule différence entre les majuscules et les minuscules A est le cinquième bit. Ce modèle continue de b à z.

donc, lorsque vous faites ^ = 32 (qui, accessoirement, est de 2 à la 5ème puissance) sur un chiffre qui représente un caractère ASCII, ce que cela va basculer le 5ème bit - si elle est 0, il devient 1, et vice versa, qui change le caractère de haut en minuscule et inversement.


5 commentaires

... Si votre implémentation C ++ utilise ASCII.


@Christianhackl I Spécialement nommé ASCII comme jeu de personnages dont je parlais dans ma réponse (puisqu'il est identique à la question de l'OP)


Oui, mais vous n'avez pas mentionné que votre implémentation C ++ n'utilise pas du tout ASCII.


Plzz me donne un exemple c'est comment je peux le comprendre facilement


@Rashedsami Cette réponse a un exemple. L'avez-vous lu avant commentaire?