Ennews:ljInj.32247$, Jean Pierre Daviau va escriure:
Oui, mais ma fonction peut copier une sous-chaîne située n'importe où dans une chaîne ... chaine
ch aine in hai ne
Il faut savoir où ça commence et où ça finit.Nn?
Ce n'est pas une caractéristique probante. En C, une sous-chaîne qui commence au n-ième caractère d'une chaîne s, cela s'écrit s+n toujours, partout, et sans se compliquer la vie à passer un argument complémentaire.
On Jan 30, 10:04 am, "Antoine Leca" <r...@localhost.invalid> wrote:
Ennews:ljInj.32247$1n5.11936@weber.videotron.net, Jean Pierre Daviau va
escriure:
Oui, mais ma fonction peut copier une sous-chaîne située
n'importe où dans une chaîne ...
chaine
ch
aine
in
hai
ne
Il faut savoir où ça commence et où ça finit.Nn?
Ce n'est pas une caractéristique probante. En C, une sous-chaîne qui
commence au n-ième caractère d'une chaîne s, cela s'écrit
s+n
toujours, partout, et sans se compliquer la vie à passer un argument
complémentaire.
Ennews:ljInj.32247$, Jean Pierre Daviau va escriure:
Oui, mais ma fonction peut copier une sous-chaîne située n'importe où dans une chaîne ... chaine
ch aine in hai ne
Il faut savoir où ça commence et où ça finit.Nn?
Ce n'est pas une caractéristique probante. En C, une sous-chaîne qui commence au n-ième caractère d'une chaîne s, cela s'écrit s+n toujours, partout, et sans se compliquer la vie à passer un argument complémentaire.
Jean Pierre Daviau
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */ #include <stdio.h> #include <stdlib.h> #include <string.h>
/* adresses alloué ailleurs */ char *dest = (char*)malloc(l_en +1); /* * dest point*ait* vers une zone de mémoire allouée dynamiquement, et cette * valeur n'est jamais sauvegardée, on va droit vers un problème de fuite mémoire... */ char *destInt = dest;
/* Vérifions si les adresses sont à l'intérieur des adresses de la chaîne. */ if(fin_sous_chaine <= fin_source){ while(debut++ < fin_sous_chaine) *dest++ = *debut;
*dest = ' '; return destInt; }
return message; }
int main(void) { char *chaine = "Chaîne de lettres.";
/* insertout.c */
/*
* Retourne une section de chaîne.
* unsigned int fin doit être <= que longueur de chaîne - 1
* strsub(char * chaine, unsigned int début, unsigned int fin)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* adresses alloué ailleurs */
char *dest = (char*)malloc(l_en +1);
/*
* dest point*ait* vers une zone de mémoire allouée
dynamiquement, et cette
* valeur n'est jamais sauvegardée, on va droit vers un problème
de fuite mémoire...
*/
char *destInt = dest;
/* Vérifions si les adresses sont à l'intérieur des adresses de
la chaîne. */
if(fin_sous_chaine <= fin_source){
while(debut++ < fin_sous_chaine)
*dest++ = *debut;
*dest = ' ';
return destInt;
}
return message;
}
int main(void)
{
char *chaine = "Chaîne de lettres.";
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */ #include <stdio.h> #include <stdlib.h> #include <string.h>
/* adresses alloué ailleurs */ char *dest = (char*)malloc(l_en +1); /* * dest point*ait* vers une zone de mémoire allouée dynamiquement, et cette * valeur n'est jamais sauvegardée, on va droit vers un problème de fuite mémoire... */ char *destInt = dest;
/* Vérifions si les adresses sont à l'intérieur des adresses de la chaîne. */ if(fin_sous_chaine <= fin_source){ while(debut++ < fin_sous_chaine) *dest++ = *debut;
*dest = ' '; return destInt; }
return message; }
int main(void) { char *chaine = "Chaîne de lettres.";
Attention c'est à proscrire absolument ! si on a oublié d'inclure le header pour malloc, malloc renvera implicitement un int qui sera converti silencieusement en pointeur. Sur certaines architectures (amd64 par ex) ces types n'ont pas la même taille. Il vaut mieux laisser le compilateur se charger du transtypage implicite, surtout quand on passe d'un void * à un char *
char *dest = (char*)malloc(l_en +1);
Attention c'est à proscrire absolument !
si on a oublié d'inclure le header pour malloc, malloc renvera
implicitement un int qui sera converti silencieusement en pointeur. Sur
certaines architectures (amd64 par ex) ces types n'ont pas la même taille.
Il vaut mieux laisser le compilateur se charger du transtypage
implicite, surtout quand on passe d'un void * à un char *
Attention c'est à proscrire absolument ! si on a oublié d'inclure le header pour malloc, malloc renvera implicitement un int qui sera converti silencieusement en pointeur. Sur certaines architectures (amd64 par ex) ces types n'ont pas la même taille. Il vaut mieux laisser le compilateur se charger du transtypage implicite, surtout quand on passe d'un void * à un char *
Michel Decima
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
/* insertout.c */
/*
* Retourne une section de chaîne.
* unsigned int fin doit être <= que longueur de chaîne - 1
* strsub(char * chaine, unsigned int début, unsigned int fin)
*/
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas
sur _debut_ ? ( et ce n'est pas teste dans le code...)
Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position
de debut et la taille, plutot que debut et fin, avec troncature
automatique si la taille demandee est plus grande que disponible
( strlen(chaine+debut) )...
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
Erwan David
Aris écrivait :
Attention c'est à proscrire absolument ! si on a oublié d'inclure le header pour malloc, malloc renvera implicitement un int qui sera converti silencieusement en pointeur. Sur certaines architectures (amd64 par ex) ces types n'ont pas la même taille.
Oui, mais ça permet à ceux qui bossent sur des architectures à entiers 16 bits et pointeurs 32 bits de se marrer...
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Aris <aris@badcode.be> écrivait :
Attention c'est à proscrire absolument !
si on a oublié d'inclure le header pour malloc, malloc renvera
implicitement un int qui sera converti silencieusement en
pointeur. Sur certaines architectures (amd64 par ex) ces types n'ont
pas la même taille.
Oui, mais ça permet à ceux qui bossent sur des architectures à entiers
16 bits et pointeurs 32 bits de se marrer...
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Attention c'est à proscrire absolument ! si on a oublié d'inclure le header pour malloc, malloc renvera implicitement un int qui sera converti silencieusement en pointeur. Sur certaines architectures (amd64 par ex) ces types n'ont pas la même taille.
Oui, mais ça permet à ceux qui bossent sur des architectures à entiers 16 bits et pointeurs 32 bits de se marrer...
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Antoine Leca
En news:47a1ef8e$0$32003$, Aris va escriure:
char *dest = (char*)malloc(l_en +1);
Attention c'est à proscrire absolument !
Ce qui devrait être proscrit, ce sont les implémentations qui fournissent un entête <stdlib.h> où malloc() n'est pas déclaré (ou qui ne signale pas d'erreur pour un entête inconnu).
si on a oublié d'inclure le header pour malloc,
Avec des si...
En l'occurence, une solution serait de déclarer explicitement malloc(), ce qui est possible si on a #inclus <stdio.h>, ou <time.h>, ou <string.h>, ou <wchar.h> etc.
Une autre « solution », qui marche très souvent voire presque toujours même si formellement c'est incorrect, est de déclarer explicitement en style ancien (K&R), avec char *malloc();
Cependant cela va poser problème quand on va (enfin) #inclure l'entête.
Bref, avec des si, on peut remplir Usenet...
Antoine
En news:47a1ef8e$0$32003$fa620c48@newsreader-1.edpnet.be,
Aris va escriure:
char *dest = (char*)malloc(l_en +1);
Attention c'est à proscrire absolument !
Ce qui devrait être proscrit, ce sont les implémentations qui fournissent un
entête <stdlib.h> où malloc() n'est pas déclaré (ou qui ne signale pas
d'erreur pour un entête inconnu).
si on a oublié d'inclure le header pour malloc,
Avec des si...
En l'occurence, une solution serait de déclarer explicitement malloc(), ce
qui est possible si on a #inclus <stdio.h>, ou <time.h>, ou <string.h>, ou
<wchar.h> etc.
Une autre « solution », qui marche très souvent voire presque toujours même
si formellement c'est incorrect, est de déclarer explicitement en style
ancien (K&R), avec
char *malloc();
Cependant cela va poser problème quand on va (enfin) #inclure l'entête.
Ce qui devrait être proscrit, ce sont les implémentations qui fournissent un entête <stdlib.h> où malloc() n'est pas déclaré (ou qui ne signale pas d'erreur pour un entête inconnu).
si on a oublié d'inclure le header pour malloc,
Avec des si...
En l'occurence, une solution serait de déclarer explicitement malloc(), ce qui est possible si on a #inclus <stdio.h>, ou <time.h>, ou <string.h>, ou <wchar.h> etc.
Une autre « solution », qui marche très souvent voire presque toujours même si formellement c'est incorrect, est de déclarer explicitement en style ancien (K&R), avec char *malloc();
Cependant cela va poser problème quand on va (enfin) #inclure l'entête.
Bref, avec des si, on peut remplir Usenet...
Antoine
Antoine Leca
En news:oykoj.9$, Jean Pierre Daviau va escriure:
* Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin)
S'il vous manque strlcpy sur votre machine, ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c (et récupérez donc en même temps ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez donc un ½il distrait à l'indicatif utilisateur de la dernière personne ayant modifié ce source... ;-) )
Antoine
En news:oykoj.9$cR.750@weber.videotron.net, Jean Pierre Daviau va escriure:
* Retourne une section de chaîne.
* unsigned int fin doit être <= que longueur de chaîne - 1
* strsub(char * chaine, unsigned int début, unsigned int fin)
S'il vous manque strlcpy sur votre machine,
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c
(et récupérez donc en même temps
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez
donc un ½il distrait à l'indicatif utilisateur de la dernière personne ayant
modifié ce source... ;-) )
* Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin)
S'il vous manque strlcpy sur votre machine, ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c (et récupérez donc en même temps ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez donc un ½il distrait à l'indicatif utilisateur de la dernière personne ayant modifié ce source... ;-) )
Antoine
j4e8a16n
On Jan 31, 11:09 am, Michel Decima wrote:
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence avant la chaîne qu'il veut diviser?
On Jan 31, 11:09 am, Michel Decima <michel.dec...@orange-ft.com>
wrote:
/* insertout.c */
/*
* Retourne une section de chaîne.
* unsigned int fin doit être <= que longueur de chaîne - 1
* strsub(char * chaine, unsigned int début, unsigned int fin)
*/
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas
sur _debut_ ? ( et ce n'est pas teste dans le code...)
Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position
de debut et la taille, plutot que debut et fin, avec troncature
automatique si la taille demandee est plus grande que disponible
( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait
problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence
avant la chaîne qu'il veut diviser?
/* insertout.c */ /* * Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence avant la chaîne qu'il veut diviser?
Michel Decima
* Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */ Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas
sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence avant la chaîne qu'il veut diviser?
Pourquoi negatif ? Si start est plus grand que la taille de la chaine, genre start = strlen(chaine)+1, ca devrait suffire, non ? (je viens de m'apercevoir que j'avais ecrit _debut_ a la place de _start_ ...)
Dans la version de Jean-Pierre, il n'y a aucun test evident dans les premieres ligne de la fonction, et s'il n'y a pas de probleme sur les indices, c'est uniquement grace a une construction obscure vers la fin. Si cette fonction echoue pour un probleme d'allocation, je recevrais NULL, c'est pas fait pour surprendre. Par contre, si elle echoue pour un probleme d'indice, je recois qd meme une chaine "Indice trop grand", et j'ai un doute serieux sur ce qui va se passer lors du free()...
Dans la version proposee par Antoine, on voit immediatement et tres clairement ce qui se passe lorsque les preconditions ne sont pas verifiees, et il y a bien les tests sur les indices que j'attendais (et si fin est superieur a la taille de la chaine, on tronque a strlen(chaine)) Et aussi, on sait quoi faire du resultat: si la fonction echoue, j'obtiens NULL, sinon je recois de la memoire dynamique que je dois desallouer.
Apres, on peut considerer le probleme de 'unsigned fin', qui est une position et pas une longueur. Si c'etait une longueur, il n'y aurait aucune ambiguite, mais comme c'est une position, il faudrait preciser si elle est comprise dans l'intervalle ou non... et visiblement Antoine et Jean-Pierre ne sont pas du meme avis :
int main(void) { char text[] = "text" ; char* s ; printf("'%s'n", ((s = strsub(text, 0, 0)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 0, 1)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 1, 1)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 1, 2)) ? s : "NULL" )); }
Les sorties sont legerement differentes:
'' '' 'e' 't' 'x' '' 'xt' 'e'
MD.
* Retourne une section de chaîne.
* unsigned int fin doit être <= que longueur de chaîne - 1
* strsub(char * chaine, unsigned int début, unsigned int fin)
*/
Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas
sur _debut_ ? ( et ce n'est pas teste dans le code...)
Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position
de debut et la taille, plutot que debut et fin, avec troncature
automatique si la taille demandee est plus grande que disponible
( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait
problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence
avant la chaîne qu'il veut diviser?
Pourquoi negatif ? Si start est plus grand que la taille de la chaine,
genre start = strlen(chaine)+1, ca devrait suffire, non ? (je viens
de m'apercevoir que j'avais ecrit _debut_ a la place de _start_ ...)
Dans la version de Jean-Pierre, il n'y a aucun test evident dans
les premieres ligne de la fonction, et s'il n'y a pas de probleme
sur les indices, c'est uniquement grace a une construction obscure
vers la fin.
Si cette fonction echoue pour un probleme d'allocation, je recevrais
NULL, c'est pas fait pour surprendre. Par contre, si elle echoue pour
un probleme d'indice, je recois qd meme une chaine "Indice trop grand",
et j'ai un doute serieux sur ce qui va se passer lors du free()...
Dans la version proposee par Antoine, on voit immediatement et tres
clairement ce qui se passe lorsque les preconditions ne sont pas
verifiees, et il y a bien les tests sur les indices que j'attendais
(et si fin est superieur a la taille de la chaine, on tronque a
strlen(chaine))
Et aussi, on sait quoi faire du resultat: si la fonction echoue,
j'obtiens NULL, sinon je recois de la memoire dynamique que je
dois desallouer.
Apres, on peut considerer le probleme de 'unsigned fin', qui est
une position et pas une longueur. Si c'etait une longueur, il n'y aurait
aucune ambiguite, mais comme c'est une position, il faudrait preciser
si elle est comprise dans l'intervalle ou non... et visiblement Antoine
et Jean-Pierre ne sont pas du meme avis :
int main(void)
{
char text[] = "text" ;
char* s ;
printf("'%s'n", ((s = strsub(text, 0, 0)) ? s : "NULL" ));
printf("'%s'n", ((s = strsub(text, 0, 1)) ? s : "NULL" ));
printf("'%s'n", ((s = strsub(text, 1, 1)) ? s : "NULL" ));
printf("'%s'n", ((s = strsub(text, 1, 2)) ? s : "NULL" ));
}
* Retourne une section de chaîne. * unsigned int fin doit être <= que longueur de chaîne - 1 * strsub(char * chaine, unsigned int début, unsigned int fin) */ Pourquoi une precondition sur _fin_ alors qu'il n'y en a pas
sur _debut_ ? ( et ce n'est pas teste dans le code...) Il faudrait aussi exiger (controler) _debut_ <= _fin_ , non ?
AMHA, l'interface serait plus agreable si on donnait la position de debut et la taille, plutot que debut et fin, avec troncature automatique si la taille demandee est plus grande que disponible ( strlen(chaine+debut) )...
Il faudrait que unsigned int start soit négatif pour qu'il y ait problème. Pourquoi quelqu'un voudrait-il une sous chaîne qui commence avant la chaîne qu'il veut diviser?
Pourquoi negatif ? Si start est plus grand que la taille de la chaine, genre start = strlen(chaine)+1, ca devrait suffire, non ? (je viens de m'apercevoir que j'avais ecrit _debut_ a la place de _start_ ...)
Dans la version de Jean-Pierre, il n'y a aucun test evident dans les premieres ligne de la fonction, et s'il n'y a pas de probleme sur les indices, c'est uniquement grace a une construction obscure vers la fin. Si cette fonction echoue pour un probleme d'allocation, je recevrais NULL, c'est pas fait pour surprendre. Par contre, si elle echoue pour un probleme d'indice, je recois qd meme une chaine "Indice trop grand", et j'ai un doute serieux sur ce qui va se passer lors du free()...
Dans la version proposee par Antoine, on voit immediatement et tres clairement ce qui se passe lorsque les preconditions ne sont pas verifiees, et il y a bien les tests sur les indices que j'attendais (et si fin est superieur a la taille de la chaine, on tronque a strlen(chaine)) Et aussi, on sait quoi faire du resultat: si la fonction echoue, j'obtiens NULL, sinon je recois de la memoire dynamique que je dois desallouer.
Apres, on peut considerer le probleme de 'unsigned fin', qui est une position et pas une longueur. Si c'etait une longueur, il n'y aurait aucune ambiguite, mais comme c'est une position, il faudrait preciser si elle est comprise dans l'intervalle ou non... et visiblement Antoine et Jean-Pierre ne sont pas du meme avis :
int main(void) { char text[] = "text" ; char* s ; printf("'%s'n", ((s = strsub(text, 0, 0)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 0, 1)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 1, 1)) ? s : "NULL" )); printf("'%s'n", ((s = strsub(text, 1, 2)) ? s : "NULL" )); }
Les sorties sont legerement differentes:
'' '' 'e' 't' 'x' '' 'xt' 'e'
MD.
Vincent Lefevre
Dans l'article <47a1fe23$0$12987$, Antoine Leca écrit:
S'il vous manque strlcpy sur votre machine, ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c (et récupérez donc en même temps ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez donc un oeil distrait à l'indicatif utilisateur de la dernière personne ayant modifié ce source... ;-) )
Et récupérez un compilateur qui reconnaisse les caractères accentués. :)
S'il vous manque strlcpy sur votre machine,
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c
(et récupérez donc en même temps
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez
donc un oeil distrait à l'indicatif utilisateur de la dernière personne ayant
modifié ce source... ;-) )
Et récupérez un compilateur qui reconnaisse les caractères accentués. :)
S'il vous manque strlcpy sur votre machine, ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c (et récupérez donc en même temps ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c, et jettez donc un oeil distrait à l'indicatif utilisateur de la dernière personne ayant modifié ce source... ;-) )
Et récupérez un compilateur qui reconnaisse les caractères accentués. :)