OVH Cloud OVH Cloud

Decalage de chaine..

23 réponses
Avatar
Xavier
Bonjour,

Voila j'essaye de creer une petit fonction "basique" de cryptage qui renvoie
le decalage d'une chaine de caractére de 1 caractere dans une autre chaine
('A' remplacer par 'B'). Si je n'effectue pas de décalage c'est ok
"//*(szOut+i) =*(szIn+i)";
Si le décalage est effectué "*(szOut+i) = (char)(*(szIn+i)+1)" cela me
renvoie la chaine décalé+ symboles qui n'ont pas lieu d'étre apres..
Voila c'est sans doute trivial mais je suis débutant et si quelqu'un avait
la réponse (et une explication sur l'échec)...

Question bis: Comment faire pour ne pas avoir à déclarer la taille de la
chaine Result (// char Result[strlen(Chaine)] ne marche pas..)
Merci d'avance
Xavier

void test_DecalageChaine ()
{
char* Chaine="La Chaine";
char Result[9];
// char Result[strlen(Chaine)];
DecalageChaine(Result,Chaine);
cout << Result << endl;
}

void DecalageChaine (char* szOut, char* szIn)
{
int i=0;
do
{
//*(szOut+i) =*(szIn+i);
*(szOut+i) = (char)(*(szIn+i)+1);
}
while (szIn[i++] != '\0');
}

10 réponses

1 2 3
Avatar
Vincent Lascaux
Question bis: Comment faire pour ne pas avoir à déclarer la taille de la
chaine Result (// char Result[strlen(Chaine)] ne marche pas..)


Utiliser std::string plutot qu'un tableau de caracteres


void test_DecalageChaine ()
{
char* Chaine="La Chaine";
char Result[9];
// char Result[strlen(Chaine)];
DecalageChaine(Result,Chaine);
cout << Result << endl;
}

void DecalageChaine (char* szOut, char* szIn)
{
int i=0;
do
{
//*(szOut+i) =*(szIn+i);
*(szOut+i) = (char)(*(szIn+i)+1);
}
while (szIn[i++] != '');
}


Ton while est dans le mauvais sens: si ta chaine est vide (szIn[i] == 0), tu
vas tout de même faire la transformation une fois (donc tu vas transformer
le caractère '', ce qui explique que la chaine transformée na plus de
fin).
Donc il faut faire

while(szIn[i] != '')
{
*(szOut+i) = *(szIn+i)+1; /* ou szOut[i] = szIn[i]+1 qui est plus
lisible je trouve */
++i;
}

En modifiant la valeur des pointeurs :
while(*szIn != '')
*(szOut++) = *(szIn++) + 1;

--
Vincent

Avatar
Matthieu Moy
"Xavier" writes:

Bonjour,


Bonjour,

Voila j'essaye de creer une petit fonction "basique" de cryptage qui renvoie
le decalage d'une chaine de caractére de 1 caractere dans une autre chaine
('A' remplacer par 'B'). Si je n'effectue pas de décalage c'est ok
"//*(szOut+i) =*(szIn+i)";


As-tu de bonnes raisons d'écrire du code aussi peu lisible ?

Une erreur commune de débutant est de croire que le code le plus court
s'execute le plus rapidement. En pratique, si tu utilise des variables
intermédiaires par exemple, ton compilo les éliminera tout seul.

Ici, tu viens de nous donner la preuve qu'il est facile d'introduire
des bugs dans du code de ce style.

void DecalageChaine (char* szOut, char* szIn)
{
int i=0;
do
{
//*(szOut+i) =*(szIn+i);
*(szOut+i) = (char)(*(szIn+i)+1);
}
while (szIn[i++] != '');
while (szIn[++i] != ''); // devrait déjà mieux marcher.

}


Tu as une boucle avec initialisation, condition d'arrêt, et une
action. La boucle for est faite pour toi.

for(int i = 0; szIn[i] != 0; ++i) {
// Pourquoi jouer avec les pointeurs alors qu'on peut utiliser les
// tableaux ?
szOut[i] = szIn[i] + 1;
}

Un bon conseil que j'aurais aimé qu'on me donne quand j'ai commencé le
C++ : oublies tout ce que tu sais sur le C, et apprends le C++
« correctement »

En espérant que ça aide ...

--
Matthieu

Avatar
Pierre Maurette
Bonjour,

Voila j'essaye de creer une petit fonction "basique" de cryptage qui renvoie
le decalage d'une chaine de caractére de 1 caractere dans une autre chaine
('A' remplacer par 'B'). Si je n'effectue pas de décalage c'est ok
"//*(szOut+i) =*(szIn+i)";
Si le décalage est effectué "*(szOut+i) = (char)(*(szIn+i)+1)" cela me
renvoie la chaine décalé+ symboles qui n'ont pas lieu d'étre apres..
Voila c'est sans doute trivial mais je suis débutant et si quelqu'un avait la
réponse (et une explication sur l'échec)...
C'est en gros du C plus que du C++.

Une erreur qui suffit à expliquer:

*(szOut+i) = (char)(*(szIn+i+1));
et non
*(szOut+i) = (char)(*(szIn+i)+1);

Préférez peut-être:
void DecalageChaine (char* szOut, const char* szIn);


Question bis: Comment faire pour ne pas avoir à déclarer la taille de la
chaine Result (// char Result[strlen(Chaine)] ne marche pas..)
(Réponse C plus que C++)


char* Chaine="La Chaine";
size_t taille = strlen(Chaine);
char* Result = (char*)malloc((taille + 1) -1);
DecalageChaine(Result,Chaine);
printf("%sn", Result);
free(Result);

taille est mal nommé et pas indispensable.
+1 -1 remplace pour moi un commentaire. Pour recopier une chaîne, il
faut réserver strlen() + 1, mais vous ne réservez que pour une chaîne
plus courte d'un caractère. malloc(taille) risque d'être confusif.
Enfin, c'est peut-être moi qui le suis, là ;-)

--
Pierre

Avatar
Matthieu Moy
"Vincent Lascaux" writes:

while(*szIn != '')
*(szOut++) = *(szIn++) + 1;


Si tu veux vraiment gagner à l'IOCCC, il faudrait plutôt quelque chose
comme :

while((*(szOut++) = *(szIn++) + 1) - 1);

Sinon, je ne vois pas trop l'intérêt ... ;-)

--
Matthieu

Avatar
Matthieu Moy
"Pierre Maurette" writes:

*(szOut+i) = (char)(*(szIn+i+1));
et non
*(szOut+i) = (char)(*(szIn+i)+1);


Oui mais non. Le PO cherche bien a faire "AaB" -> "BbC" et non
"AaB" -> "aB".

--
Matthieu

Avatar
Pierre Maurette
"Pierre Maurette" writes:

*(szOut+i) = (char)(*(szIn+i+1));
et non
*(szOut+i) = (char)(*(szIn+i)+1);


Oui mais non. Le PO cherche bien a faire "AaB" -> "BbC" et non
"AaB" -> "aB".
Je m'étais (très rapidement) posé la question. Mais le

char Result[9];
m'avais enduit d'erreur. C'était donc un
char Result[10];

A ce moment-là, il suffit de clore la chaîne résultat, par exemple par
un
*(szOut + i - 1) = '';
bien placé.
Mais il faudrait peut-être affiner le cahier des charges, puis
l'analyse. En fait, il faudrait savoir si le fichier crypté doit rester
"du texte"

--
Pierre


Avatar
Xavier
Ok Merci a tous,
Le probleme n'était pas tant la forme du bouclage (while/do..while/for) mais
plutot le caractére de fin de chaine a préciser en final
*(szOut + i - 1) = '';
Ce qui explique que cela marchait sans décalage de chaine et échouait avec
un décalage.
Merci quand même pour les conseils de bouclage..

PS: En fait c'est pas pour crypter un fichier mais une chaine a stocker dans
le registre
Xav


"Pierre Maurette" a écrit dans le message de
news:
"Pierre Maurette" writes:

*(szOut+i) = (char)(*(szIn+i+1));
et non
*(szOut+i) = (char)(*(szIn+i)+1);


Oui mais non. Le PO cherche bien a faire "AaB" -> "BbC" et non "AaB" ->
"aB".
Je m'étais (très rapidement) posé la question. Mais le

char Result[9];
m'avais enduit d'erreur. C'était donc un
char Result[10];

A ce moment-là, il suffit de clore la chaîne résultat, par exemple par un
*(szOut + i - 1) = '';
bien placé.
Mais il faudrait peut-être affiner le cahier des charges, puis l'analyse.
En fait, il faudrait savoir si le fichier crypté doit rester "du texte"

--
Pierre





Avatar
Pierre Maurette
Ok Merci a tous,
Le probleme n'était pas tant la forme du bouclage (while/do..while/for) mais
plutot le caractére de fin de chaine a préciser en final
*(szOut + i - 1) = '';
Ce qui explique que cela marchait sans décalage de chaine et échouait avec un
décalage.
Merci quand même pour les conseils de bouclage..

PS: En fait c'est pas pour crypter un fichier mais une chaine a stocker dans
le registre
J'imagine que vous ne cherchez pas effectivement un cryptage solide,

mais une résistance aux fonctions de recherche de chaîne (de regedit
par exemple). Votre truc semble suffisant, mais je me demande s'il n'y
a pas un danger. Est-il garanti que votre algo transforme une chaîne
valide pour la BdR en une chaîne valide pour la BdR ?
Vous avez l'alogo rot13 (que vous pouvez modifier) qui serait peut-être
mieux adapté.
Vous trouverez certainement du code source par Google. Par exemple ici:
http://minilien.com/?YVTOLdzrCe

--
Pierre

Avatar
Vincent Lascaux
while(*szIn != '')
*(szOut++) = *(szIn++) + 1;


Si tu veux vraiment gagner à l'IOCCC, il faudrait plutôt quelque chose
comme :

while((*(szOut++) = *(szIn++) + 1) - 1);

Sinon, je ne vois pas trop l'intérêt ... ;-)


Ils prennent des programmes qui ne fonctionnent pas à l'IOCCC ? :'P
Les deux programmes ne sont pas équivalents puisque dans le tiens le
décalage se fera au moins une fois... On pourrait résoudre ton "bug" en
rajoutant par la suite *(szOut-1) = 0;
Mais j'aime pas trop : ca fait un peu trop récup de choses mal faites.

Quant à la lisibilité de mon code, je pense que ce que j'ai écrit est
relativement classique... On se sert de szOut et de szIn comme des
iterateurs sur la chaine. Les seules choses qu'on puisse lui reprocher sont
1) on devrait utiliser d'autres variables pour iterer sur la chaine (mais
bon... ca ne me dérange pas plus que ca)
2) on pourrait mettre les incrémentations sur une autre ligne. Dans ce cas,
j'ai du mal à imaginer une utilisation interessante de l'opérateur ++ (int).
Mais soit.

--
Vincent


Avatar
Xavier
Trés juste, l'objectif est simplement ne pouvoir retrouver facilement la
chaine avec un regedit.
Merci pour le lien vers Rot13, Pierre
Xavier

"Pierre Maurette" a écrit dans le message de
news:
Ok Merci a tous,
Le probleme n'était pas tant la forme du bouclage (while/do..while/for)
mais plutot le caractére de fin de chaine a préciser en final
*(szOut + i - 1) = '';
Ce qui explique que cela marchait sans décalage de chaine et échouait
avec un décalage.
Merci quand même pour les conseils de bouclage..

PS: En fait c'est pas pour crypter un fichier mais une chaine a stocker
dans le registre
J'imagine que vous ne cherchez pas effectivement un cryptage solide, mais

une résistance aux fonctions de recherche de chaîne (de regedit par
exemple). Votre truc semble suffisant, mais je me demande s'il n'y a pas
un danger. Est-il garanti que votre algo transforme une chaîne valide pour
la BdR en une chaîne valide pour la BdR ?
Vous avez l'alogo rot13 (que vous pouvez modifier) qui serait peut-être
mieux adapté.
Vous trouverez certainement du code source par Google. Par exemple ici:
http://minilien.com/?YVTOLdzrCe

--
Pierre




1 2 3