Menu

Ecrire fonction strlcpy

stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention - 13 nov. 2017 à 00:14 - Dernière réponse : Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention
- 15 nov. 2017 à 00:47
Bonjour,

Je dois ecrire strlcpy en C, j'ai du mal a comprendre le man et je l'ai lu plusieurs fois.

Je vous explique d'abord ce que j'ai compris, dite moi si vous etes pas d'accord avec moi.

man strcpy
Elle prend 2 paramètres on doit copier src dans dest puis on ajoute un '\0' et on retourne dest
Si dest est plus courte que src alors on retourne les x caractères de src copier dans dest

man strncpy
Elle prend 3 paramètres on doit copier les n premiers caractères de src dans dest puis on ajoute des '\0' si nécessaire quand dest est plus long que src.

man strlcpy (ça devient compliquer)
Elle prend 3 paramètres (char *dest, char *src, unsigned int size)
Elle retourne la longueur qui est copiable de src dans dest.
En parallele il faut copier size - 1 caracteres de src dans dest et mettre un '\0' à la fin. La longueur retourner sera egale aux nombres de caracteres qui inclut le '\0'
Que doit on retourner si dest est plus court que src, que doit on copier dans dest ?

Merci pour votre aide

https://www.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3

http://manpagesfr.free.fr/man/man3/strcpy.3.html

Afficher la suite 

Votre réponse

8 réponses

Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention - 13 nov. 2017 à 00:45
0
Merci
Bonjour,
Je trouve le man plus clair que tes explications!

strlcpy(dest,src,lgMax)
doit copier le plus de caractères possible de
src
dans
dest
, la taille max dans
dest
est
lgMax
.
Contrairement à
strncpy(dest,src,lgMax)
elle doit garantir que le terminateur est toujours écrit dans
dest[]
(si
src
est trop longue, il sera à la position
dest[lgMax-1]
, sinon
dest
sera une simple copie de
src
).
La fonction doit retourner la longueur de
src
.
stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention - 13 nov. 2017 à 22:55
Je veux etre sûr d'avoir bien compris

exemple
dest = "avion"
src = "bateau"
unsigned int size = 3

on va copier src dans dest donc le nouveau dest = "ba\0\0\0\0"
Tu es d'accord avec l'idée de ajouter suffisament de '\0' ?

valeur retourner 2 + 1, le 1 correspond '\0' tu valides ?

J'ai dit 2 + 1 à cause de cette phrase dans le man qui m'a mis le doute :
"functions return the total length of the string they tried to create."

autre cas
dest = "avion"
src = "bateau"
unsigned int size = 8

nouveau dest = ""bateau"\0
valeur retourner 6 + 1 c'est ça ?

https://www.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3

Tu es d'accord avec moi ?
Si c'est bon je pense avoir compris la subtilité de cette fonction.
Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention > stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention - 13 nov. 2017 à 23:25
Relis le man

exemple
dest = "avion"
src = "bateau"
unsigned int size = 3

on va copier src dans dest donc le nouveau dest = "ba\0on\0" (max 3 caractères terminateur compris, les autres ne sont surtout pas modifiés)
Tu es d'accord avec l'idée de ajouter suffisament de '\0' ?
Non c'est pas dans le man.
valeur retourner 3 + 1, le 1 correspond '\0' tu valides ?
Non, on retourne 6 la longueur de "bateau" et le '\0' n'est pas compté
J'ai dit 3 + 1 à cause de cette phrase dans le man qui m'a mis le doute :
"functions return the total length of the string they tried to create."
En effet texte ambiguë, mais le man précise "For strlcpy() that means the length of src."

autre cas

dest = "avion"
src = "bateau"
unsigned int size = 8

nouveau dest = "bateau"\0 Oui
valeur retourner 6 + 1 c'est ça ? Non 6
stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention > Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention - 14 nov. 2017 à 00:06
"on va copier src dans dest donc le nouveau dest = "ba\0on\0" (max 3 caractères terminateur compris, les autres ne sont surtout pas modifiés)
Tu es d'accord avec l'idée de ajouter suffisament de '\0' ?
Non c'est pas dans le man."


Oui excuse moi j'ai fait un raccourci tordu avec la fonction strncpy. Il faut ajouter un seul '\0'

Pour la valeur retourner, celle ci correspond à la valeur de src. Je rappelle que src n'est jamais modifié donc sa longueur reste inchangée, seul dest est modifié.

Si tu valides mes explications je pense avoir compris.
stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention > Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention - 14 nov. 2017 à 23:42
"autre cas

dest = "avion"
src = "bateau"
unsigned int size = 8

nouveau dest = "bateau"\0 Oui
valeur retourner 6 + 1 c'est ça ? Non 6"


Après réflexion je pense que cet exemple devrait planter. ? Après le sixième caractère on essaie de lire dans de la mémoire qui n'existe pas.
Dalfab 340 Messages postés dimanche 7 février 2016Date d'inscription 14 juin 2018 Dernière intervention > stell-91 243 Messages postés dimanche 25 décembre 2011Date d'inscription 6 juin 2018 Dernière intervention - 15 nov. 2017 à 00:47
Si on a respecté le contrat, il ne plante pas (la size 8 doit être <= à la taille du buffer dest)
char dest[8];
strcpy( dest , "avion" );
strlcpy( dest , "bateau" , 8 );
// ne plante pas

char *dest = "avion avec beaucoup de place";
strlcpy( dest , "bateau" , 8 );
// est un Undefined Behaviour, qui peut planter ou pas (sur un PC plante rarement, dans l'embarqué plante souvent) car une chaîne littérale est un pointeur sur une zone qui ne doit pas être écrite
La ligne 6 doit provoquer un warning en C, et c'est une erreur en C++.
Commenter la réponse de Dalfab