Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème de concaténation

6 réponses
Avatar
Yves Lange
Bonjour/soir,

voilà un petit programme que j'ai conçu mais je ne maîtrise pas très
bien le C.

------------------------------------------------------------------------
// file: deca.c
# include <stdio.h>

main(){
// Liste des fichiers à manipuler.
char *lTab[] = {"c:\\test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};

system(sCommand);
return 0;
}
------------------------------------------------------------------------

Quelqu'un sait-il pourquoi la compilation se passe sans problème mais
lors de l'exécution, windows me retourne un message d'erreur. On dirait
qu'il a un problème de taille dans *sCommand[] ou de dépassement de
tampon mais je n'en suis pas sûre. Merci d'avance pour votre aide.

Yves Lange

6 réponses

Avatar
Pascal Bourguignon
Yves Lange writes:

Bonjour/soir,

voilà un petit programme que j'ai conçu mais je ne maîtrise pas très
bien le C.

------------------------------------------------------------------------
// file: deca.c
# include <stdio.h>

main(){
// Liste des fichiers à manipuler.
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};

system(sCommand);
return 0;
}
------------------------------------------------------------------------

Quelqu'un sait-il pourquoi la compilation se passe sans problème mais
lors de l'exécution, windows me retourne un message d'erreur. On
dirait qu'il a un problème de taille dans *sCommand[] ou de
dépassement de tampon mais je n'en suis pas sûre. Merci d'avance pour
votre aide.


Pour ce que j'en sais,

1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.

2- Je ne crois pas qu'il soit possible d'utiliser des expressions dans
les litéraux {} d'initialisation.

3- strcat demande une chaîne MUTABLE comme destination, et contenant
assez d'espace pour le résultat. "cato.exe " n'est ni mutable, ni
assez grande (à moins que lTab[0]=="").

4- main doit retourner un int.


Et je ne vois pas pourquoi tu utilise des tableaux d'un seul élément,
à quoi ça rime?


Aussi, les fonctions de bibliothèque standard C sont plutôt
rudimentaire; il vaudrait mieux écrire des fonctions de plus haut
niveau, gérant les détails de l'allocation de la mémoire, etc.

Si on écrivait (pseudo-code):


int main(void){
string_t argument=string_from_c("C:TEST.TXT");
string_t command=string_concatenate(string_from_c("CATO.EXE "),argument,0);
printf("%dn",string_to_c(command));
system(string_to_c(command));
return(0);
}


On serait sur que ça fait ce qu'on veut. Ensuite, il suffirait
d'implémenter correctement les fonctions manquantes.


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


const int out_of_memory=1;

void raise_error(int code){
fprintf(stderr,"Error %dn",code);
exit(1);
}

void* allocate(size_t size){
void* result=malloc(size);
if(result==0){
raise_error(out_of_memory);
}else{
return(result);
}
}


typedef struct string_t {
int allocated_size;
char* bytes;
}* string_t;


string_t string_new(size_t allocation){
string_t result=allocate(sizeof(*result));
result->allocated_size=allocation;
result->bytes=allocate(result->allocated_size);
result->bytes[0]=''; /* empty string */
return(result);
}

string_t string_from_c(const char* cstring){
string_t result=string_new(1+strlen(cstring));
strcpy(result->bytes,cstring);
return(result);
}

const char* string_to_c(string_t str){
return(str->bytes);
}

int string_length(string_t str){
return(strlen(str->bytes));
}

string_t string_concatenate(string_t str,...){
size_t totlen=0;
size_t curlen=0;
string_t result;
string_t current;
va_list ap;
va_start(ap,str);
for(current=str;current!=0;current=va_arg(ap,string_t)){
totlen+=string_length(current);
}
va_end(ap);
result=string_new(1+totlen);
va_start(ap,str);
for(current=str;current!=0;current=va_arg(ap,string_t)){
strcpy(result->bytes+curlen,current->bytes);
curlen+=string_length(current);
}
va_end(ap);
return(result);
}


--
__Pascal Bourguignon__ http://www.informatimago.com/

"Logiciels libres : nourris au code source sans farine animale."

Avatar
Thomas Labourdette
Pascal Bourguignon a écrit le vendredi 8 décembre 2006 16:02 :

Yves Lange writes:
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};


Pour ce que j'en sais,

1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.



Tu peux me dire pourquoi, dans son code, sCommand peut-être initialisé avant
lTab ?

@+
--
Kévin ASSE-CEBORDEAU (signature et citation aléatoires)
LOI (à la con)
Il est illégal pour toute personne de sexe masculin, a l'intérieur des
limites de la ville, de faire un clin d'oeil a toute personne de sexe
féminin qu'il ne connaît pas. (Ottumwa, Iowa)


Avatar
Pierre Maurette
Pascal Bourguignon a écrit le vendredi 8 décembre 2006 16:02 :

Yves Lange writes:
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};


Pour ce que j'en sais,

1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.



Tu peux me dire pourquoi, dans son code, sCommand peut-être initialisé avant
lTab ?


Je ne trouve pas ça très très étonnant. sCommand[] est un tableau de
char*, initialisé à la valeur const char* "cato.exe " considérée comme
une constante immédiate par le compilateur.
Ceci dit, le contraire m'aurait encore moins étonné, au motif de la
fonction strcat().

--
Pierre Maurette



Avatar
Eric Levenez
Le 8/12/06 16:02, dans , « Pascal
Bourguignon » a écrit :

Yves Lange writes:

# include <stdio.h>

main(){
// Liste des fichiers à manipuler.
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};

system(sCommand);
return 0;
}


1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.


Ce n'est pas de haut en bas ?

2- Je ne crois pas qu'il soit possible d'utiliser des expressions dans
les litéraux {} d'initialisation.


Le mieux est en effet de supprimer les accolades des 2 affectations qui ne
servent à rien du tout.

3- strcat demande une chaîne MUTABLE comme destination, et contenant
assez d'espace pour le résultat. "cato.exe " n'est ni mutable, ni
assez grande (à moins que lTab[0]=="").

4- main doit retourner un int.


5 - il manque les includes string.h pour strcat et stdlib.h pour system.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Pascal Bourguignon
Eric Levenez writes:

Le 8/12/06 16:02, dans , « Pascal
Bourguignon » a écrit :

Yves Lange writes:

# include <stdio.h>

main(){
// Liste des fichiers à manipuler.
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};

system(sCommand);
return 0;
}


1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.


Ce n'est pas de haut en bas ?


Peut être dans le cas de variable auto locales, oui.

Mais dans le cas de variable statiques, je ne crois pas que le
standard impose un quelconque ordre.

2- Je ne crois pas qu'il soit possible d'utiliser des expressions dans
les litéraux {} d'initialisation.


Le mieux est en effet de supprimer les accolades des 2 affectations qui ne
servent à rien du tout.

3- strcat demande une chaîne MUTABLE comme destination, et contenant
assez d'espace pour le résultat. "cato.exe " n'est ni mutable, ni
assez grande (à moins que lTab[0]=="").

4- main doit retourner un int.


5 - il manque les includes string.h pour strcat et stdlib.h pour system.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



--
__Pascal Bourguignon__ http://www.informatimago.com/

HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.



Avatar
Thomas Labourdette
Pierre Maurette a écrit le vendredi 8 décembre 2006 18:14 :

Pascal Bourguignon a écrit le vendredi 8 décembre 2006 16:02 :

Yves Lange writes:
char *lTab[] = {"c:test.txt"};
char *sCommand[] = {strcat("cato.exe ", lTab[0])};


Pour ce que j'en sais,

1- L'ordre de l'initialisation des variables n'est pas spécifié. Il
est possible que sCommand soit initialisé avant lTab, alors lTab[0]
peut être invalide.



Tu peux me dire pourquoi, dans son code, sCommand peut-être initialisé
avant lTab ?


Je ne trouve pas ça très très étonnant.


Qu'est-ce qui n'est pas très étonnant ?
Entre lTab et sCommand, il y a un point de séquencement donc lTab est
initialisé avant sCommand (la prise en compte étant de haut en bas).

@+
--
Bill BOKAI (signature et citation aléatoires)
Qu'est-ce qui fait 13,2 cm mais qui excite les femmes ?
Un billet de 500 Euros.