2017-06-11 5 views
-1
#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    int key; 
    char line[500]; 
    char ch = '\0'; 
    int i = 0; 

    printf("Enter key: "); 
    scanf("%d", &key); 
    getchar(); 

    printf("Enter line: "); 

    while(ch != '\n') 
    { 
     ch = getchar(); 
     line[i] = ch; 
     i++;  
    } 

    int length = i; 
    int k = 0; 
    char temp[length]; 

    for(i = 0; i < length; i++) 
    { 

     if((int)line[i] >= 65 && (int)line[i] <= 90) 
     {   
       temp[k++] = (int)line[i] + key; 
     } else if((int)line[i] >= 97 && (int)line[i] <= 122){ 
       temp[k++] = (int)line[i] + key; 
     } else { 
      temp[k++] = line[i]; 
     } 
    } 

    printf("\n"); 

    for(i = 0; i < length; i++) 
    { 
     printf("%c", temp[i]); 
    } 
} 

Ce que j'ai fait jusqu'à présent est de convertir les caractères en un autre. Par exemple, si je saisis "abc ABC" et que la valeur ajoutée (int) est 3, alors il faut imprimer "def DEF".Gestion des alphabets ASCII en C

Cela fonctionne très bien, mais ce que je veux réaliser est de rembobiner le caractère s'il n'est pas lié. Par exemple, si je saisis "XYZ" et que la valeur ajoutée est 3, cela devrait imprimer "ABC", pas "[]". Puis-je obtenir de l'aide ou un conseil pour résoudre ce problème? Merci ..

+2

Utiliser l'opération modulo. –

+0

Désolé mais que dois-je faire avec un fonctionnement modulo? – seung

+0

pas besoin de 'cast' ici, car des promotions entières ont implicitement lieu. –

Répondre

1

Tout d'abord, quand je vois

if((int)line[i] >= 65 && (int)line[i] <= 90) 

ma première réaction est: "Qu'est-ce que 65 et 90 signifie?" Bien, je sais, mais encore, ces nombres étaient une nuisance inutile pour que vous compreniez et ils sont une nuisance inutile pour que le lecteur lise. Il suffit donc de dire

if(line[i] >= 'A' && line[i] <= 'Z') 

à la place. En C, la valeur d'une constante de caractère comme 'A' est la valeur du caractère dans le jeu de caractères de la machine, ou 65 en ASCII. (Je me suis débarrassé de quelques moulages inutiles, aussi.)

Ensuite, une sorte de passage force brute de résoudre votre problème serait de vérifier juste pour trop-plein:

if(line[i] >= 'A' && line[i] <= 'Z') 
{ 
    temp[k] = line[i] + key; 
    if(temp[k] > 'Z') 
     temp[k] -= 26; 
    k++; 
} 

Depuis que je devais faire plusieurs choses avec temp[k] avant que j'en avais fini avec elle, j'ai déplacé le k++ à la fin.

Vous utiliseriez un code similaire pour le cas a-z.

Si vous souhaitez rendre le programme plus général, il est également possible que key soit négatif. Dans ce cas, vous devez vous soucier des lettres "moins que" A, aussi. Vous pouvez étendre le code comme ceci:

if(line[i] >= 'A' && line[i] <= 'Z') 
{ 
    temp[k] = line[i] + key; 
    if(temp[k] > 'Z') 
     temp[k] -= 26; 
    else if(temp[k] < 'A') 
     temp[k] += 26; 
    k++; 
} 

Encore une fois, vous répéteriez ceci pour le cas a-z. Maintenant, la méthode non-brute-force consiste à reconnaître que l'arithmétique «enveloppante» que nous faisons ici est ce que l'on appelle aussi l'arithmétique du «module», car elle est liée au «module» ou au «reste». "opérateur, %. Donc, si vous comprenez comment % œuvres, vous pouvez écrire du code comme ceci:

if(line[i] >= 'A' && line[i] <= 'Z') 
{ 
    int c = line[i] - 'A'; 
    c = (c + key) % 26; 
    temp[k++] = c + 'A'; 
} 

Il est pas encore tout à fait simple, parce que nous devons passer d'une lettre comme « Y », à sa position de base 0 dans la alphabet (25), à sa valeur décalée (28, en supposant un key de 3), à sa valeur "modulo" {2}, puis finalement à une lettre comme "B".

Ou, plus en détail, ce qui se passe est que les lettres majuscules sont, en ASCII, 65 à 90. Donc, nous soustrayons 65 pour obtenir des nombres dans la gamme 0-25. Une fois que nous sommes dans la plage de 0 à 25, nous pouvons utiliser l'arithmétique du module, car % 26 signifie fondamentalement "seulement des nombres entiers compris entre 0 et 25". Finalement, lorsque nous aurons terminé l'arithmétique de notre module, nous en rajouterons 65, pour revenir à la plage 65-90 des lettres réelles. (Et au lieu de soustraire et ajouter 65, nous soustrayons et ajoutons 'A', parce que c'est la même valeur, mais plus claire.)

Et, encore une fois, je montre toujours seulement le code pour les lettres majuscules; il faudrait aussi répéter ce code pour le cas a-z.

+1

Que se passe-t-il si le décalage est de 300? indice - ça ne va pas fonctionner. – RoiHatam

+0

@RoiHatam Bien sûr. Mais (a) il ne va pas faire cela (ou ne va pas s'attendre à ce que cela fonctionne), et (b) nous construisons à «%» par étapes faciles. –

+0

Si j'utilise ce cas, je perds mon 'espace' Comment dois-je éviter de le perdre? – seung