2016-02-13 1 views
2

J'ai un programme ici où j'essaye de décoder une chaîne de lettres en utilisant un chiffre de césar; essentiellement je déplace chaque caractère dans la chaîne "vers le bas" une lettre ("a" -> "b", "f" -> "g", "z" -> "a").Erreur de segmentation dans le code C en utilisant `string` à partir de cs.50.h

Le montant que je déplace une lettre dépend de la clé que je lui donne.

Dans ce programme spécifique, j'ai un message codé secret codé en dur dans la fonction main(), et une boucle for itérant à travers chaque touche possible. L'idée est que si ce message secret est simplement décalé vers le bas de x quantité de lettres, cracher 25 versions du chiffre révélera une réponse intelligible.

Malheureusement, j'utilise des concepts qui sont nouveaux pour moi - argc, argv, et plusieurs fonctions dans un seul programme. Je suis très nouveau à cela. Est-ce que quelqu'un peut aider à expliquer l'erreur de segmentation que j'obtiens? Je ne pense pas que je provoque des débordements sur les arguments.

#include <stdio.h> 
#include <cs50.h> 
#include <string.h> 

string decode(int key, string message); 

int main(void) 
{ 
    string secret_message = "ueuag rKJ AGIQ GIAR FEgN"; 

    for (int i = 0; i < 25; i++) 
    { 
     decode(i, secret_message); 
     printf("%s", secret_message); 
    } 

    return 0; 
} 

string decode(int key, string message) 
{ 
    int i; 

    for (i = 0; i < strlen(message); i++) 
    { 
     if (message[i] >= 'a' && message[i] <= 'z') 
     { 
      message[i] = ((message[i] - 97 + key) % 26) + 97; 
     } 
     else if (message[i] >= 'A' && message[i] <= 'Z') 
     { 
      message[i] = ((message[i] - 65 + key) % 26) + 65; 
     } 
    } 

    return message; 
} 
+0

Ce 'pour (i = 0; i

+2

Ne connaissant pas sa définition, je suppose que passer 'string' directement à' printf' n'est pas bon. – MikeCAT

+0

Quelle langue utilisez-vous, C ou C++? Qu'est-ce que 'string'? – aschepler

Répondre

7

Pourquoi string une mauvaise idée pour un type à ?, Ici vous pouvez voir un exemple. Vous modifiez une chaîne littérale et vous ne devriez pas. Le faire invoque un comportement indéfini. Au lieu d'avoir un type string, vous devez traiter les chaînes comme étant ce qu'elles sont dans .

Au lieu de cela le faire comme ce

char secret_message[] = "ueuag rKJ AGIQ GIAR FEgN"; 

Et la fonction decode

char *decode(int key, char *message) 
{ 
    int i; 

    for (i = 0; message[i] != '\0'; i++) 
    { 
     if (message[i] >= 'a' && message[i] <= 'z') 
     { 
      message[i] = ((message[i] - 97 + key) % 26) + 97; 
     } 
     else if (message[i] >= 'A' && message[i] <= 'Z') 
     { 
      message[i] = ((message[i] - 65 + key) % 26) + 65; 
     } 
    } 

    return message; 
} 

Comme vous pouvez le voir je traite la chaîne comme un tableau parce que c'est ce qu'il est, un tableau d'octets avec '\0' à la fin. Si vous saviez cela, vous ne feriez jamais quelque chose comme typedef char * string parce que c'est très trompeur.

Dans cs50.hstring est un typedef pour un pointeur char, et un pointeur est pas une chaîne, une chaîne de caractères est une séquence d'octets et un pointeur char * peut pointer vers un tableau de char qui pourrait être une chaîne si vous le définissez et l'initialisez correctement. Mais un pointeur char * pourrait pointer vers une chaîne littérale, et vous ne pouvez pas les modifier qui est pas clair si vous définissez comme

string string_literal = "Do not attempt to modify me, it's undefined behavior"; 

Lorsque vous déclarez un pointeur vers une chaîne de caractères, vous devez utiliser const char * pour éviter accidentaly essayer pour le modifier.

En outre, typedef pointeurs ING à mon avis n'a aucun avantage et provoque beaucoup de confusion, un pointeur est un pointeur et doit avoir un * près de son identifiant lorsqu'il a déclaré, si vous supprimez la nécessité d'un * vous pouvez facilement oublier les pointeurs dans le code et être confus.

+0

Merci pour votre commentaire informatif. J'ai tout changé à et j'ai le même problème –

+1

@DavidManess S'il vous plaît continuez à lire comme je mets à jour la réponse, voir ma suggestion -> "* Vous ne pouvez pas écraser une chaîne littérale *". –

+1

@DavidManess Changer 'string' en' char * 'n'aidera pas, car' string' est déjà un typedef pour 'char *'. Vous devez déclarer votre 'secret_message' comme un' char [] ', pas un' char * '(ou' string'), alors le programme fonctionnera. – Paul