web-dev-qa-db-fra.com

Est-il légal de passer une chaîne non terminée par null à strncmp en C?

J'ai un tableau de 16 octets qui contient le nom du segment d'un exécutable.

char segname[16];

Si la longueur du nom de segment est inférieure à 16 octets, le reste est rempli avec des octets nuls. Sinon, il n'y a pas d'octet nul final.

Je veux comparer segname à différentes chaînes, par exemple __text.

Est-il légal d'appeler strncmp avec une chaîne non terminée par null?

Ce message suppose qu'il est légal. Ce code source le rend également légal. Mais la page de mon homme dit:

La fonction strncmp() compare lexicographiquement les chaînes à terminaison nulle s1 Et s2.

La taille passée à strncmp sera la taille de segname.

Je me demande à quoi je dois me référer.

45
Bilow

Selon la norme C99, section 7.21.4.4, §3., Il est légal:

La fonction strncmp renvoie un entier supérieur, égal ou inférieur à zéro, en conséquence comme le tableau éventuellement terminé par un caractère nul pointé par s1 est supérieur, égal ou inférieur au tableau éventuellement terminé par un caractère nul pointé par s2.

Notez, cependant, qu'il dit tableau de caractères. Par définition, si un tableau de caractères n'est pas terminé par un caractère nul, c'est pas une chaîne.

67
giusti

La fonction strncmp ne compare pas plus de n caractères (les caractères qui suivent un caractère nul ne sont pas comparés) du tableau pointé par s1 au tableau pointé par s2.

La spécification 7.24.4.2 indique que .norme C11.

Les caractères qui ne suivent pas un caractère nul ne sont pas comparés, il attend donc un tableau ou une chaîne de caractères à caractère nul.1

Vous pouvez également utiliser des caractères non nuls ici mais dans ce cas, nous devons spécifier la longueur jusqu'à laquelle nous devons le vérifier, ce qui est utile dans certains cas.

Corrections


[1]Le fait que les caractères qui ne suivent pas un caractère nul ne soient pas comparés ne signifie pas que strncmp attend des chaînes terminées par null. Cela signifie simplement que strncmp a besoin d'un cas spécial pour dire (par exemple) que abc\0def... et abc\0xyz... comparer égal. Il n'y a rien de mal à comparer deux tableaux de caractères qui ne se terminent pas par null (jusqu'à la longueur spécifiée) ou à comparer un tableau de caractères terminé par null avec un autre qui n'est pas terminé par null
Ceci est directement ajouté à partir du commentaire de David Hammen

15
user2736738