OVH Cloud OVH Cloud

Proposition man strcpy, strncpy

22 réponses
Avatar
Marc Boyer
Bonjour,

suite à de précedentes discussions, je vais faire une nouvelle
proposition pour les pages de man Linux de strcpy, strncpy,
strcat, strncat.

Voici ma proposition actuelle pour strcpy, strncpy. Tous
commentaires bienvenus.


STRCPY(3) Linux Programmer's Manual STRCPY(3)

NAME
strcpy, strncpy - copy a string

SYNOPSIS
#include <string.h>

char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, size_t n);

DESCRIPTION
The strcpy() function copies the string pointed to by src (including
the terminating `\0' character) to the array pointed to by dest. The
strings may not overlap, and the destination string dest must be large
enough to receive the copy.

The strncpy() function is similar, except that not more than n bytes of
src are copied. Thus, if there is no null byte among the first n bytes
of src, the result will not be null-terminated.

In the case where the length of src is less than that of n, the remain-
der of dest will be padded with nulls.

An (very poor quality) implementation of strncpy() could be

char*
strncpy(char *dest, const char *src, size_t n){
size_t i;
for(i=0 ; i < strlen(src) && i < n; i++){
dest[i]= src[i];
}
for(i=strlen(src)+1 ; i < n ; i++){
dest[i]= '\O';
}
return dest;
}

RETURN VALUE
The strcpy() and strncpy() functions return a pointer to the destina-
tion string dest.

BUGS
If the destination string of a strcpy() is not large enough (that is,
if the programmer was stupid/lazy, and failed to check the size before
copying) then anything might happen. Overflowing fixed length strings
is a favourite cracker technique.

A common mistake with strncpy() is to forget that it, if
strlen(src) >= n, then, the '\O' termination character is not set.

NOTE
Some programmers consider strncpy() as useless. If the programmer knows
the the size of dest is greater than the length of src, then, strcpy()
can be used. Otherwise, using strncpy() makes a non null terminated
string.

At least, lazy programmers should write:
strncpy(foo, bar, n);
foo[n-1]= '\0';

CONFORMING TO
SVID 3, POSIX, BSD 4.3, ISO 9899

SEE ALSO
bcopy(3), memccpy(3), memcpy(3), memmove(3)

GNU 1993-04-11 STRCPY(3)

--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

2 réponses

1 2 3
Avatar
Marc Boyer
Charlie Gordon wrote:
"Marc Boyer" wrote in message
news:clah72$e3p$
In article <cl6o5o$hr7$, Charlie Gordon wrote:
"Marc Boyer" wrote in message
news:cl5ed6$7p4$



De plus, le test sur i<n doit etre fait avant de déréférencer src pour le
cas ou


n==0


Alors là, ça devient rude à écrire.


En fait c'est très simple : dans ton exemple, il suffit d'écrire : i < n && i <
strlen(src)


Sauf que j'ai décide de faire un unique appel à strlen
size_t src_len= strlen(src);

De toute façon, je vais reposter une version complète, car à
force de parle de modifs de modifs, ça devient difficile à suivre.

Le problème avec strlen(src) c'est que c'est un très mauvais exemple pour les
lecteur de la page de manuel à cause de l'inefficacité crasse que cela implique
pour un test de boucle. De plus c'est sémantiquement incorrect pour strncpy ou
src peut très bien ne pas contenir de '' final et strlen(src) a donc
potentiellement un comportement indéfini.


Oui, donc j'ai remplacé par un appel unique.

strncpy could be implemented as:

char *strncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n && src[i] != ''; i++)
dest[i]= src[i];
for (; i < n; i++)
dest[i] = '';
return dest;
}


Non, si je veux toucher aussi les débutants, je préfère strlen,
mais en effet, si n==0, faut pas appeller strlen().


pas seulement dans ce cas (cf plus haut). strlen n'est pas une option, il faut
en passer par le test de ''.


Est-ce à dire que, pour strncat, même si n!=0, la chaine src
n'a pas à être "nul terminated" ?

Et que penses-tu de:

Programmers often prevent this mistake by forcing '' termination
this way:

strncpy(buf, str, n);
if (n) buf[n - 1]= '';

If n can not be nul, the test can be removed.


Je dirais alors:

if (n != 0) {
strncpy(buf, str, n);
buf[n - 1] = '';
}

ce qui a le même résultat, mais met l'emphase sur le comportement vide dans le
cas n==0, qui n'est pas si évident dans ton code.


Non, car on pourrait croire qu'une précondition à l'appel de strncpy
est que n soit non nul.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.



Avatar
Charlie Gordon
"Marc Boyer" wrote in message
news:cliot2$1o2$

Est-ce à dire que, pour strncat, même si n!=0, la chaine src
n'a pas à être "nul terminated" ?


Tout à fait. C'est le cas aussi bien pour strncpy que pour strncat. On peut
écrire:

char buf[10];
char *p = malloc(100);
if (p) {
memset(p, 'x', 100);
strncpy(buf, p, 10);
buf[5] = '';
strncat(buf, p, sizeof(buf) - strlen(buf) - 1);
}

dans ce cas, strlen(p) a un comportement indéfini, mais le code est correct.


if (n != 0) {
strncpy(buf, str, n);
buf[n - 1] = '';
}

ce qui a le même résultat, mais met l'emphase sur le comportement vide dans
le


cas n==0, qui n'est pas si évident dans ton code.


Non, car on pourrait croire qu'une précondition à l'appel de strncpy
est que n soit non nul.


Il peut effectivement y avoir confusion, mais strncpy ne fait rien si n==0

Chqrlie.


1 2 3