XI. c_strncat▲
XI-A. Prototype▲
char
*
c_strncat (
char
*
dest, const
char
*
src, c_size_t n);
XI-B. Description et comportement▲
La fonction c_strncat concatène n caractères de la chaine src vers la chaine dest. Si la fonction rencontre un caractère de fin de chaine durant les n caractères elle s'arrête et sinon, la fonction ne copie pas plus que la longueur n.
Quel que soit le cas de figure, la fonction ajoute un caractère nul pour marquer la fin de la chaine dest !
Si la chaîne src est vide alors la chaîne dest sera inchangée.
La concaténation commençant à la fin de la chaine dest, si celle-ci ne dispose pas d'un caractère de fin de chaine, la fonction continue la recherche de ce dernier jusqu'à en trouver un. Par conséquent l'écriture se fera alors dans une zone de mémoire quelconque pouvant entraîner un comportement indéterminé de votre programme en plus d'un potentiel écrasement des données en mémoire.
Il faut par conséquent s'assurer que les chaines de caractères possèdent un zéro terminal et également que la chaine dest soit assez grande pour stocker la chaine src en plus de ses propres caractères et bien sûr son zéro de fin !
XI-C. Algorithme▲
Voici un algorithme possible pour la fonction c_strncat :
algorithme
fonction c_strncat (dest:chaîne, src:chaîne, n:entier):chaîne
debut
i <- 0
j <- longueur (dest)
faire
dest[j] <- src[i]
j <- j + 1
i <- i + 1
tant que n <- n - 1 et src[i] différent de '\0'
retourne dest;
fin
lexique
dest : chaine : Chaine de destination, adresse renvoyée par la fonction.
src : chaine : Chaine source.
n : entier : Nombre de caractères à copier.
i : entier : Variable d'incrémentation pour se déplacer dans la chaine src.
j : entier : Variable d'incrémentation pour se déplacer dans la chaine dest.
Nous commençons par déclarer deux variables pour le déplacement dans les chaines dest et src. Ici i pour la chaine src que nous initialisons à 0 et j pour la chaine dest que nous initialisons à la longueur de la chaine dest, on se positionne donc sur le caractère de fin de celle-ci.
La boucle parcourt de 0 jusqu'à n les caractères de la chaine src ou jusqu'à trouver un caractère de fin de chaine (en réalité cet algorithme est identique à celui de la fonction c_strcat à part l'instruction de décrémentation qui vient s'ajouter dans la condition de la boucle).
Dans le corps de la boucle, nous copions le caractère courant et nous incrémentons les variables i et j.
À la sortie de la boucle nous retournons l'adresse de la chaine dest.
Complexité temporelle dans le pire des cas : |
---|
Dans le pire des cas n>=taille(src) : complexité en O(taille(src)+C(c_strlen(dest)) |
XI-D. Implémentation▲
char
*
c_strncat (
char
*
dest, const
char
*
src, c_size_t n)
{
const
char
*
p1 =
src;
char
*
p2 =
dest +
c_strlen (
dest);
do
{
*
p2++
=
*
p1++
;
}
while
(
n--
&&
*
p1);
return
dest;
}
Tout comme la fonction c_strcat précédente, l'implémentation change un petit peu, car elle est adaptée à l'utilisation des pointeurs, je n'entrerai donc pas dans les détails d'implémentation ici, car ceci a déjà été dans le chapitre précédent !
XI-E. Tests▲
#include "c_string.h"
#include <stdio.h>
int
main (
void
)
{
char
str1 [30
] =
"
Ma chaine
"
;
const
char
str2 [] =
"
de caracteres !
"
;
c_strncat (
str1, str2, 14
);
printf (
"
str1 : %s
\n
"
, str1);
return
0
;
}
Dans ce programme de test, on ne concatène qu'une partie de la chaine str2 donc ici jusqu'au caractère s. On peut tester également le comportement de la fonction si elle trouve un zéro de fin durant les n caractères par exemple avec une chaine str2 ci-dessous :
const
char
str2 [] =
"
de carac
\0
teres !
"
;