Bonjour à tous ,
je voudrais savoir si le fait de remplir une chaîne de caractère par des '0' empêche la fonction printf()
d'afficher la chaîne entière et l'oblige à n'afficher qu'un seul "0" ,prenant les autres pour des fins de chaîne ('\0') ?
Version imprimable
Bonjour à tous ,
je voudrais savoir si le fait de remplir une chaîne de caractère par des '0' empêche la fonction printf()
d'afficher la chaîne entière et l'oblige à n'afficher qu'un seul "0" ,prenant les autres pour des fins de chaîne ('\0') ?
Quelle est la question ?
'0' n'a rien à voir avec \0, le premier est le caractère 0, le nombre 0, le second est le caractère null, de fin de chaîne.
printf comme la majorité des fonctions C de traitement de chaînes de caractères s'arrêtera au premier \0.
Initialiser une chaîne avec des \0 peut être une bonne pratique et éviter des déboires.
Ok ,
J'ai une routine de codage de chaîne de caractères composée de '0' et '1' :
Le problème c'est que la variable codeBin ne semble contenir qu'un unique caractère alors qu"elle "devrait" être aussiCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 char *codage(char *clairBin) { int i,j,cle,binSize,pas; char *codon,*codeBin,*codeLimit; // binSize = strlen(clairBin); cle = (binSize/8); pas = cle-1; // codon = malloc(cle+1); codon[cle] = '\0'; // codeBin = malloc(binSize+1); codeBin[binSize] = '\0'; for(i=0;i<8;i++) { j = 0; strncpy(codon,clairBin+(i*cle),cle); printf("codon %d : %s\n",i,codon); codeLimit = codeBin+((i*cle)+pas); //printf("codeLimit = %u\n",codeLimit); while(j < cle) { switch (codon[j]) { case '0': //printf("%c",codon[j]); codeBin[(i*cle)+j] = codon[j]; j++; if(j < cle) { //printf("-%c",codon[j]); *codeLimit = codon[j]; codeLimit--; j++; } break; default:// '1' //printf("%c",codon[j]); codeBin[(i*cle)+j] = codon[j]; j++; break; } } } printf("\ncodeBin : %s\n",codeBin); return codeBin; }
longue que la chaîne paramètre de la fonction .
Est-ce que quelqu'un voit quelque chose car je ne vois plus rien !!!
Bonjour
Me semble déjà que "cle" devrait être plus longue de 1 à cause de la perte dans la division (ben oui, si la chaine d'origine est longue par exemple de 4, alors "cle" vaudra 0 ce qui n'est pas tiptop pour une zone mémoire à réserver). En fait, la bonne formule devrait être cle=(binSize-1)/8 + 1.
De plus tes strncpy(codon,clairBin+(i*cle),cle)) réécrasent à chaque fois le contenu de "codon". Tu ne pensais pas plutôt à strncat() ???
Quoi qu'il arrive, fais attention car ces fonctions arrêtent la copie soit quand la fin de la chaine à copier est atteinte ; soit quand elles ont copié "n" caractères. Mais dans ce dernier cas, elles ne positionnent pas de '\0'.
printf() n'affiche jamais de '\0' (ni plusieurs, ni même un seul). De plus, elle ne peut pas prendre "les autres" pour des fins de chaine puisqu'elle s'arrête au premier (elle ne verra donc pas "les autres"). Et même pire, si elle continuait après le premier '\0' rencontré pour regarder ce qu'il y a après, comment saurait-elle alors où s'arrêter ???
Exact ,mais le truc (pour l'instant ) c'est que aucunes chaîne parvenant à la fonction n'est plus petite que 24 caractères et qq soient leur nombre
ils sont toujours multiples de 8.
codon est effectivement écrasé à chaque tour de boucle et cela est bien car son contenu n'a plus d'importance une fois traité.
As-tu essayé la fonction et si oui peux tu dire pourquoi la chaîne finale contient un seul caractère ?
Ok. Ta formule fonctionne donc pour ce cas particulier. Mais la mienne fonctionne pour tous les cas...
Ok
Je te sens un peu aggressif. Pourtant j'ai fait des efforts (et je pensais que tu me connaissais un peu là dessus). J'ai effectivement essayé mais ne sachant pas à l'origine tes entrées à 24c, j'avais mis "toto". Et après avoir remplacé ta formule par la mienne ; et remplacé strncpy() par strncat(), j'ai vu "codon" se remplir au fur et à mesure et "codeBin" contenait bien "toto". Donc pour moi c'était bon. C'est pas ma faute si ça ne fonctionne pas.
Effectivement en mettant "000011110000111100001111" (soit 24 caractères) je n'en ai plus qu'un seul en final. Mais en mettant "abcdefghijklmnopqrstuvwx" ça me ressort tout correctement. Le souci vient donc de la chaine entrée et de son traitement. Et en mettant "111111111111111111111111" ça me ressort aussi tout correctement.
Accessoirement, pour plus de précision, "codeBin" ne contient pas qu'un seul caractère. Il en contient plein. Si tu n'en vois qu'un seul, c'est parce que le second vaut '\0' et que printf() s'arrête alors à cette valeur.
Je fais donc quelques essais (à ta place). Avec 8 ou 16 "0" ça va mais avec 24 ou 32 ça ne va plus. Là, je commence à penser au comportement indéterminé surtout avec ton j++ qui se fait tantôt une fois, tantôt deux fois ; et ce codelimit-- lui aussi un peu erratique. Mais c'est certainement de ma faute si je ne comprends pas ce que tu fais car j'ai qu'à lire les nombreux commentaires de ton algo...
Je laisse ton printf("codon %d : %s\n",i,codon) mais je rajoute printf("i=%d, codon[%d]=%d\n",i, j, codon[j]) juste avant le switch() et printf("i=%d, j=%d, codeBin[%d]=%d\n",i, j, i*cle+j, codeBin[i*cle+j]) juste après et voici ce que ça me sort à l'écran (pour une chaine contenant 24 "0")
Donc que remarque-t-on ? Au premier tour de boucle tu remplis codeBin[2]. Mais que contient codeBin[0] et codeBin[1] ??? Et ensuite à chaque tour de boucle chaque codeBin[x] (avec x multiple de 3) vaut 0. Or la valeur 0 (qu'on peut aussi représenter par le caractère '\0') est la valeur qui indique "fin de chaine". Donc toute fonction qui lira ta chaine s'arrêtera au premier 0 (ou '\0') rencontré. Et qu'il se trouve que déjà ce 0 (ou '\0') est positionné au 3° caractère (donc quoi qu'il y ait après printf() n'en lira jamais plus de 2) mais qu'en plus comme tu n'as rien indiqué concernant les deux premiers, il se trouve que cette zone mémoire (qui contient alors n'importe quoi) contient alors ici spécialement (pasdbol) un caractère '\0' et au final donc tu n'en vois plus qu'un seul...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 moi@virtualux:/tmp$ make a cc a.c -o a moi@virtualux:/tmp$ ./a cle=3 codon 0 : 000 i=0, codon[0]=48 i=0, j=2, codeBin[2]=48 i=0, codon[2]=48 i=0, j=3, codeBin[3]=0 codon 1 : 000 i=1, codon[0]=48 i=1, j=2, codeBin[5]=48 i=1, codon[2]=48 i=1, j=3, codeBin[6]=0 codon 2 : 000 i=2, codon[0]=48 i=2, j=2, codeBin[8]=48 i=2, codon[2]=48 i=2, j=3, codeBin[9]=0 codon 3 : 000 i=3, codon[0]=48 i=3, j=2, codeBin[11]=48 i=3, codon[2]=48 i=3, j=3, codeBin[12]=0 ...etc etc jusqu'à i=7 et j=24... codeBin : 0 x=0
Je pense que tu devrais revoir intégralement ton algo. Ou nous expliquer ce que tu cherches à faire. Surtout avec ce codeLimit qui vient en plus interférer dans le truc...
Je m'excuse si j'ai pu te faire penser cela ; ta réputation n'est certes pas à faire sur ce forum et je m'en voudrais
de te manquer de respect.
C'est effectivement de la mienne et j'ajoute que je l'ai un peu fait exprès car je ne tiens pas à renseigner ce code
que je souhaite obscurcir davantage !
Là tu m'épates !!!!
Tes réflexions sont si profondes que tu arrives toujours à mettre le doigt où ça cloche avec les mots
et la pédagogie qui conviennent.
Encore merci Sve@r
Bah, ça peut arriver. Et puis parfois moi aussi j'agace certains intervenants selon ma façon de leur répondre... :chin:
Tu y es déjà bien arrivé car il t'a obscurci toi aussi. Ce que je te conseille toutefois c'est de commencer par écrire un code simple qui fonctionne puis ensuite seulement de l'obscurcir. Ceci dit, la sécurité d'un protocole ne se fait généralement pas en obfusquant son code source mais plutôt dans sa complexité mathématique. Pour exemple j'ai eu en main le premier source de la fonction "password()" qui permet de générer un mot chiffré à partir d'un mot de passe en clair et qui était utilisée par les premiers Unix (ceux qui chiffraient sur 8 caractères). Ben j'ai jamais su l'inverser. Il y avait des rotations de matrices etc etc c'était horrible.
Tu as raison et je suis entièrement d'accord en ce qui concerne le domaine de la cryptographie à clés publiques qui utilise
des algorithme mathématiques à sens unique ; par contre ,dans la branche à clés privées ,les algorithmes eux-mêmes
sont les clés et par conséquent il convient de ne pas les divulgués ou de les rendre très difficiles à comprendre (ton
exemple fait foi) .
Cela dit en toute modestie car je ne me prétend pas capable d'écrire de tels algorithmes résistants aux tentatives
de déchiffrement :oops: