OVH Cloud OVH Cloud

Concaténation

13 réponses
Avatar
Matt...
Bonjour,

soit

const char *szRepertoire =3D "/home/moi/rep";
const char *szFichier =3D "fichier";
char szChemin[REP_LEN + FIC_LEN + 1] =3D {0};

je souhaiterais concat=C3=A9ner szRepertoire et szFichier dans szChemin.=
Quel =

est la meilleur fa=C3=A7on de faire (optimis=C3=A9 temps d'ex=C3=A9cutio=
n car =C3=A9norm=C3=A9ment =

de fichier) ?

sprintf(szChemin, "%s/%s", szRepertoire, szFichier);

ou

strcpy(szChemin, szRepertoire);
strcat(szChemin, "/");
strcat(szChemin, szFichier);

Merci pour vos r=C3=A9ponses,

Matt....

-- =

Utilisant le logiciel de courrier r=C3=A9volutionnaire d'Opera : =

http://www.opera.com/mail/

3 réponses

1 2
Avatar
Samuel DEVULDER
Le 23/06/2013 11:46, Matt... a écrit :

strcpy(szChemin, szRepertoire);
strcat(szChemin, "/");
strcat(szChemin, szFichier);





J'ai fait quelques testes et la deuxième méthode s'avère plus rapide.



Du point de vu algorithmique le code ci-dessus repasse plusieurs fois
sur le début de szChemin. Dans l’absolu on peut faire mieux avec une
opération de recopie qui retourne un pointeur sur le final:

char *stpcpy(char *d, char *s) { // existe en iso-c
while((*d++ = *s++));
return d-1;
}

==> stpcpy(stpcpy(stpcpy(szChemin, szRepertoire), "/"), szFichier);

En pratique ca ne changera rien avec les tailles de szRepertoire
habituelles (quelques centaines d'octets). La majorité du temps sera
passée dans les entrées/sorties pour la recopie du fichier.

Mais si strlen(szRepertoire) faisait quelques centaines de Mo (de très
grosses chaines), la relecture permanente de ce préfix à chaque
strcat(szChemin, ...) finirait par couter des cycles cpu pour rien.

Bref: du point de vu théorique, si on l'utilise mal strcat() peut
facilement te faire passer un algorithme d'une complexité O(n) à O(n^2)
avec n=taille des chaines. Dans ce cas il vaut mieux utiliser stpcpy.

Je passe outre le fait que strcat, strcpy, stpcpy sont des méthodes
dangereuses dans la mesure où elles ont vite fait de déborder le buffer.

sam.
Avatar
Antoine Leca
Samuel DEVULDER écrivit :
char *stpcpy(char *d, char *s) { // existe en iso-c



Peux-tu expliciter ta pensée exprimée de manière lapidaire dans le
commentaire ?

char *stpcpy(char *d, char *s) { // existe en iso-c
while((*d++ = *s++));
return d-1;
}



Pour info, stpcpy() est normalisé dans XPG (aussi connu sous les noms
X/Open et XSI, et dont le texte fait partie intégrante de la norme ISO
9945 dite «POSIX», sans que la conformité en soit exigée pour la norme
ISO 9945 proprement dite ; autrement dit, c'est une extension X/Open).

Les différences (const, restrict) avec ton implémentation sont mineures.
Par contre, le fait d'utiliser la version fournie par le compilateur va
probablement amener de bien meilleures performances.


Antoine
Avatar
Samuel DEVULDER
Le 24/06/2013 16:07, Antoine Leca a écrit :
Samuel DEVULDER écrivit :
char *stpcpy(char *d, char *s) { // existe en iso-c



Peux-tu expliciter ta pensée exprimée de manière lapidaire dans le
commentaire ?



C'est ce que tu précises ci-après: le compilo peut le connaitre ou pas
suivant qu'il est posix (mais MS-DOS non posix connait aussi cette fonction)

Ce qui compte dans mon message c'est plus l'algo que la norme: ne pas
repasser sans arret la lecture du préfixe dans chaque strcat(). Les nom
des standards et moi font parfois deux, car dans le fond ce qui importe
vraiment et de savoir si le compilo connait ou pas la fonction (et
qu'elle fait ce qu'on attend). S'il la connait: tant mieux on l'utilise.
Sinon on se la rajoute à sa bibliothèque d'utilitaires propre au projet.

Pour info, stpcpy() est normalisé dans XPG (aussi connu sous les noms
X/Open et XSI, et dont le texte fait partie intégrante de la norme ISO
9945 dite «POSIX», sans que la conformité en soit exigée pour la norme
ISO 9945 proprement dite ; autrement dit, c'est une extension X/Open).

Les différences (const, restrict) avec ton implémentation sont mineures.
Par contre, le fait d'utiliser la version fournie par le compilateur va
probablement amener de bien meilleures performances.



Oui, voila.

sam.
1 2