OVH Cloud OVH Cloud

Problème bizarre de concatenation

19 réponses
Avatar
nico
Bonjour,

Soit le morceau de code suivant :

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

int main(int argc, char ** argv)
{

/* Blabla */

char* str;

if(argc >= 2)
{
int i;
str = argv[1];

for(i = 2; i < argc; ++i)
{
strcat(str, " ");
strcat(str, argv[i]);
}
}

printf("%s\n", str);
return 0;
}

pourquoi si j'apelle mon prog par :

./prog salut ceci est un test

ca m'affiche "salut est un test" ?

j'ai trouvé une autre méthode qui consiste a remplacer les deux strcat par :

sprintf(str, "%s %s", str, argv[i]);

et là ca fonctionne.

Quelle est la meilleure méthode (si toutefois la première marchait) ?


Merci.

--
nico

9 réponses

1 2
Avatar
Yves ROMAN
"Emmanuel Delahaye" a écrit dans le message de news:

nico wrote on 20/06/05 :
int main(int argc, char ** argv)

str = argv[1];

strcat(str, " ");


Comportement indéfini. Tu ne sais pas si l'argument est modifible, ni si
il peut être agrandi.



Au fait, ca ne serait pas plus logique qu'il y ait un const dans la
définition de argv ?


Avatar
Marc Boyer
Comportement indéfini. Tu ne sais pas si l'argument est modifible, ni si
il peut être agrandi.



Au fait, ca ne serait pas plus logique qu'il y ait un const dans la
définition de argv ?


Oui mais const a été introduit en 89, et je suppose qu'il
ne fallait pas casser le code existant.
Après, j'aurais bien imaginé deux signatures possibles
pour main: une avec const, l'autre sans. Mais ça n'a pas
été fait. Peut-être qu'il y a une raison qui m'échappe.

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Horst Kraemer
"Yves ROMAN" wrote:

"Emmanuel Delahaye" a écrit dans le message de news:

nico wrote on 20/06/05 :
int main(int argc, char ** argv)

str = argv[1];

strcat(str, " ");


Comportement indéfini. Tu ne sais pas si l'argument est modifible, ni si
il peut être agrandi.



Au fait, ca ne serait pas plus logique qu'il y ait un const dans la
définition de argv ?


Alors il faudrait renoncer à

The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their
last-stored values between program startup and program termination.

ce qui rendrait invalides beaucoup de programmes. Quel serait
l'avantage d'une restriction?

N:B:: on a le droit de *modifier* le "string" pointé par argv[1] mais
on n'a pas le droit de le *prolonger*.

--
Horst



Avatar
Emmanuel Delahaye
Yves ROMAN wrote on 21/06/05 :
Au fait, ca ne serait pas plus logique qu'il y ait un const dans la
définition de argv ?


Si, et rien ne l'empêche.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."

Avatar
Emmanuel Delahaye
Emmanuel Delahaye wrote on 20/06/05 :
nico wrote on 20/06/05 :
int main(int argc, char ** argv)

str = argv[1];

strcat(str, " ");


Comportement indéfini. Tu ne sais pas si l'argument est modifible, ni si il
peut être agrandi.


Ok, il est modifiable, mais ne peut pas être agrandi.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

.sig under repair


Avatar
Antoine Leca
En <news:,
Emmanuel Delahaye va escriure:
Antoine Leca wrote on 20/06/05 :
Sinon, une bonne méthode consiste à mettre un caractère « qui ne
peut pas arriver » (je mettais souvent '¤' avant les euros, comme il
était au clavier)


Je faisais ça aussi avec -1 ou je ne sais quel caractère bizarre
jusqu'à ce qu'un 'smart guy' de c.l.c me fasse remarqué que 0 était la
bonne valeur.


Oui, c'est vrai, 0 est la bonne valeur par rapport à ce que j'ai expliqué
(la dernière case du tableau).

En fait, je me sers de ce mécanisme pour détecter aussi les erreurs de 1 sur
les déclarations ou (inclusif) les copies, donc les cas où tu te retrouve
avec un '' imprévu dans l'octet qui _suit_ le tableau réservé (cas
classique du bogue strncat()). Et là le but du jeu c'est justement de savoir
si un '' a été écrit par erreur de débordement, donc pour ce caractère de
dépassement, 0 n'est _pas_ la bonne valeur.


Antoine


Avatar
Antoine Leca
En <news:42b6fd81$0$686$, nico va escriure:
ok. à la fin de la zona allouée tu veux dire ?

par exemple :

char * str = malloc(nb);
str[nb - 1] = '?';


Oui. Comme le fait remarquer Emmanuel, 0 est la bonne valeur pour
initialiser.


Antoine

Avatar
Antoine Leca
En <news:, Emmanuel Delahaye
va escriure:
str = argv[1];
strcat(str, " ");


Comportement indéfini. Tu ne sais pas si l'argument est modifible,
ni si il peut être agrandi.


Ok, il est modifiable, mais ne peut pas être agrandi.


Ah... Je m'apprêtais à saisir mon clavier...


Antoine



Avatar
Emmanuel Delahaye
Antoine Leca wrote on 22/06/05 :
En <news:,
Emmanuel Delahaye va escriure:
Antoine Leca wrote on 20/06/05 :
Sinon, une bonne méthode consiste à mettre un caractère « qui ne
peut pas arriver » (je mettais souvent '¤' avant les euros, comme il
était au clavier)


Je faisais ça aussi avec -1 ou je ne sais quel caractère bizarre
jusqu'à ce qu'un 'smart guy' de c.l.c me fasse remarqué que 0 était la
bonne valeur.


Oui, c'est vrai, 0 est la bonne valeur par rapport à ce que j'ai expliqué
(la dernière case du tableau).

En fait, je me sers de ce mécanisme pour détecter aussi les erreurs de 1 sur
les déclarations ou (inclusif) les copies, donc les cas où tu te retrouve
avec un '' imprévu dans l'octet qui _suit_ le tableau réservé (cas
classique du bogue strncat()). Et là le but du jeu c'est justement de savoir
si un '' a été écrit par erreur de débordement, donc pour ce caractère de
dépassement, 0 n'est _pas_ la bonne valeur.


Relis mes macros. Le zéro 'sentinelle' doit être placé à sa place
maximale théorique.

char s[4];

s[4 - 1] = 0;

Si le 0 disparait c'est qu'il y a eu débordement.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."



1 2