Fondamentalement, mon code est censé crypter une phrase (ou un mot) en supprimant toutes les valeurs d'index numérotées paires (à partir de 0) et les valeurs d'index impaires et en plaçant les valeurs d'index paires avant les valeurs d'index impaires. Par exemple, un mot comme "test" (0) t (1) e (2) s (3) t doit être imprimé comme (0) t (2) s (1) e (3) t ou "tset". Il n'est pas censé y avoir de nombres imprimés, je les ai juste utilisés pour afficher les valeurs d'index paires et impaires. Mon code fonctionne parfois, selon l'endroit où il est exécuté. Je semble obtenir des résultats différents entre les blocs de code et un compilateur en ligne que j'ai essayé. Je soupçonne qu'il doit y avoir un problème plus important à blâmer pour cette incohérence. Quelqu'un peut-il m'aider à voir ce que je fais mal pour que je puisse enfin comprendre et corriger mes erreurs?
J'ai essayé d'utiliser un compteur pour saisir des valeurs d'index paires et impaires dans un seul tableau, mais j'avais des erreurs avec cela comme Eh bien, j'ai donc décidé de les mettre dans des tableaux séparés, puis d'utiliser strcat pour les combiner. Y a-t-il un moyen de le faire fonctionner avec la méthode que j'ai montrée dans mon code ou dois-je revenir à la méthode précédente?
#include <stdio.h>
#include <string.h>
#define SIZE 1000
int main()
{
char message[SIZE];
char even[SIZE];
char odd[SIZE];
int length,j=0;
printf("Enter a word or sentence.\n");
fgets(message,SIZE,stdin);
printf("Your message is: %s\n",message);
message[strcspn(message, "\n")] = 0;
length=strlen(message);
printf("The length of the message is: %d\n",length);
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
// printf("%c\n",even[i/2]);
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
strcat(even,odd);
printf("%s",even);
/*printf("\nFInalyy.");
for(i=0;i<=count;i++)
for(j=i+1;j<=count;j++){
if(strcmp(allmessages[i],allmessages[j])>0){
strcpy(temp,allmessages[i]);
strcpy(allmessages[i],allmessages[j]);
strcpy(allmessages[j],temp);
}
}
printf("The original messages in alphabetical order are: ");
for(i=0;i<=count;i++)
puts(allmessages[i]);*/
return 0;
}
Cela fonctionne parfaitement lorsque je tape des mots comme «test» ou «phrase». Parfois, je tape des phrases comme "ceci est une phrase de test" et cela fonctionnerait parfaitement, puis une fois, il imprimait des lettres de déchets aléatoires avec la phrase cryptée. Je voudrais savoir comment résoudre ce problème et comprendre pourquoi cela fonctionne parfaitement avec la même entrée plusieurs fois puis s'arrête. J'ai utilisé https://www.onlinegdb.com/online_c_compiler pour le tester ces dernières fois. les résultats sont basés sur cela.
Résultat réussi:
Résultat d'échec en utilisant la même entrée:
3 Réponses :
Les chaînes en C ne connaissent pas leur longueur, ce ne sont que des pointeurs. Les chaînes doivent être terminées par un caractère nul pour que des fonctions telles que printf et strlen sachent quand s'arrêter.
void copy_every_other_character(const char *src, char *dst) {
int i,j,length = 0;
length = strlen(src);
for( i=0,j=0; i<length; i+=2,j++ ) {
dst[j] = src[i];
}
dst[j] = '\0';
}
copy_every_other_character(message, even);
copy_every_other_character(message+1, odd);
À ce stade pair et impair contiennent tous les deux les déchets qui se trouvaient en mémoire à ce moment-là.
for( i=0,j=0; i<length; i+=2,j++ ) {
even[j]=message[i];
}
even[j] = '\0';
for( i=1,j=0; i<length; i+=2,j++ ) {
odd[j]=message[i];
}
odd[j] = '\0';
Maintenant, le début de impair et pair ont été renseignés, mais ils ne sont pas terminés par une valeur nulle.
for(i=0;i<length;i+=2){
even[i/2]=message[i];
}
even[i/2] = '\0';
for(i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
odd[j] = '\0';
Ceux-ci commenceront à l'endroit où pair et impair , imprimez les caractères que vous avez mis là-dedans, puis continuez à imprimer les déchets qui se trouvaient en mémoire jusqu'à ce qu'ils atteignent un caractère nul.
Le correctif consiste soit à remettre à zéro la mémoire avec memset.
memset(even, '\0', SIZE); memset(odd, '\0', SIZE);
soit à s'assurer que même et impairs sont annulés une fois que vous en avez terminé avec eux.
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
Remarque, pair et impaires peuvent être faites avec la même technique.
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
Ensuite, nous pouvons observer que la seule différence est l'endroit où nous commençons à lire message . Cela signifie que nous pouvons mettre cela dans une fonction et toujours nous souvenir de null pour terminer le résultat.
char even[SIZE]; char odd[SIZE];
Ajouter 1 à message signifie copy_every_other_character obtiendra un pointeur vers le deuxième caractère du message et continuera à partir de là. Si message est 01234 , il verra 1234.
De plus, "Les chaînes en C ne connaissent pas leur longueur, ce ne sont que des pointeurs." favorise la vue chaînes comme des pointeurs, où les chaînes ressemblent plus à des tableaux que dans «Une chaîne est une séquence contiguë de caractères terminés par et incluant le premier caractère nul. ".
@chux Je pense que c'est trop subtil pour ce niveau de compréhension. Je ne sais même pas où vous voulez en venir. L'important est que tout ce que vous voulez appeler doit être terminé par null.
Vous pouvez adopter une approche légèrement plus courte en utilisant simplement deux index pour créer votre chaîne chiffrée (comme evenstart et oddstart ) en fonction de la longueur totale du message saisi par l'utilisateur. evenstart = 0; et oddstart = (msglen + 1) / 2;
Ensuite, bouclez simplement sur les caractères du message saisi par l'utilisateur en écrivant des caractères pairs à encrypt [evenstart ++] et les caractères impairs à encrypt [oddstart ++] . (n'oubliez pas de nul-terminate encrypt si vous comptez l'utiliser comme chaîne à des fins de sortie.
En l'assemblant, vous pouvez le faire :
$ ./bin/encrevenodd enter message: tes message : 'tes' encrypt : 'tse' $ ./bin/encrevenodd enter message: test message : 'test' encrypt : 'tset' $ ./bin/encrevenodd enter message: tests message : 'tests' encrypt : 'tsset' $ ./bin/encrevenodd enter message: my dog has fleas message : 'my dog has fleas' encrypt : 'm o a laydghsfes'
( remarque: vous pouvez utiliser i% 2 pour vérifier pair / impair si vous le souhaitez, ou simplement i & 1 - en binaire, si le bit à un est 1 c'est impair, sinon c'est pair - à vous de décider)
Exemple d'utilisation / de sortie
#include <stdio.h>
#include <string.h>
#define MAXC 1024
int main (void) {
char message[MAXC],
encrypt[MAXC];
size_t len, evenstart = 0, oddstart;
fputs ("enter message: ", stdout);
if (!fgets (message, MAXC, stdin)) { /* validate message entered */
fputs ("(user canceled input)\n", stdout);
return 1;
}
message[(len = strcspn(message, "\r\n"))] = 0; /* trim '\n', get len */
oddstart = (len + 1) / 2; /* get oddstart (add 1 before divide) */
for (size_t i = 0; i < len; i++) /* loop over each char */
if (i & 1) /* if odd, write char at oddstart */
encrypt[oddstart++] = message[i];
else /* if even, write at evenstart */
encrypt[evenstart++] = message[i];
encrypt[len] = 0; /* nul-terminate */
printf ("message : '%s'\nencrypt : '%s'\n", message, encrypt);
}
Regardez les choses et faites-moi savoir si vous avez des questions.
Les chaînes en C se terminent par l'octet nul ('\ 0' ou valeur ascii 0) juste pour qu'il sache où la chaîne se termine. Les tableaux de caractères pairs et impairs n'étant pas terminés par l'octet nul, strcat ne sait pas quand arrêter l'ajout de caractères. Les valeurs inutiles que vous voyez sont donc dues au fait que strcat continue d'ajouter des caractères jusqu'à ce que vous trouviez heureusement un 0 en mémoire.
La publication de texte sous forme de texte est plus utile que la publication de texte sous forme d'image. Veuillez remplacer les images par du texte.