web-dev-qa-db-fra.com

Avantages de strncmp sur strcmp?

Il semble que strncmp soit généralement recommandé par rapport à strcmp, quels sont les avantages? Je pense que cela pourrait être lié à la sécurité. Si tel est le cas, est-il toujours applicable si l'une des chaînes en entrée est connue pour être une constante littérale, telle que "LiteralString"?

UPDATE: Je veux dire dans le même scénario d'utilisateur où des chaînes entières doivent être comparées, et strncmp peut être utilisé comme ci-dessous. Je me demande si cela a du sens ou non.

strncmp(inputString, "LiternalString", strlen("LiternalString"));
9
Thomson

Le problème avec strcmp est que, parfois, si, par erreur, les arguments transmis ne sont pas des chaînes C valides (ce qui signifie que p1 ou p2 ne sont pas terminés par un caractère nul, c’est-à-dire pas Chaîne terminée par NULL ) , strcmp continue à comparer jusqu'à atteindre une mémoire non accessible et se bloque ou entraîne parfois un comportement inattendu.

En utilisant strncmp, vous pouvez limiter la recherche afin qu'elle n'atteigne pas la mémoire non accessible.

Mais, à partir de cela, il ne faut pas dire que strcmp est précaire. Les deux fonctions fonctionnent bien dans la manière dont elles sont censées fonctionner. Le programmeur doit lire la page man pour cette fonction avant de l’utiliser et doit être suffisamment sincère pour transmettre les paramètres à ces fonctions de bibliothèque. 

Vous pouvez également lire THIS qui contient une question presque similaire.

17
Surajeet Bharati

strncmp n'a pas "d'avantages par rapport à strcmp"; ils résolvent plutôt des problèmes différents. strcmp sert à déterminer si deux chaînes sont égales (et si non, comment les ordonner/les trier les unes par rapport aux autres). strncmp est (principalement) pour déterminer si une chaîne commence par un préfixe particulier. Par exemple:

if (strncmp(str, "--option=", 9)==0)

déterminera si str commence par "--option=". Ceci ne peut pas être réalisé avec strcmp sans modifier la chaîne à vérifier (opération qui peut ne pas être valide) ou en faire une copie inutile. Cela ne peut pas non plus être réalisé avec memcmp à moins que vous ne sachiez déjà que str pointe sur un objet d’une longueur minimale de 9 octets; sinon l'appel à memcmp aurait un comportement indéfini.

Il existe également d'autres cas d'utilisation pour strncmp, tels que le travail avec des données non C-string.

10
R..

Tout dépend de vos cas d'utilisation. Utilisez strncmp si vous devez seulement comparer un nombre fixe de caractères, utilisez strcmp si vous devez comparer une chaîne entière.

C'est à peu près ça.

8
int ret1, ret2;
char dev1[]  = { "ABC" };
char dev2[4] = { "ABC" };

dev2[3] = 'D';
ret1 = strncmp(dev1,dev2,strlen(dev1));  // # of characters
ret2 = strncmp(dev1,dev2,sizeof(dev1));  // # of characters plus '\0'

supposons que: dev1 soit null terminé et dev2 probablement pas. ret1 = 0 (résultat faux positif), plutôt que ret2 = -1 (résultat valide)

fazit: strncmp n’est pas seulement un moyen plus sûr pour strcmp. Cela dépend de la façon dont vous l'utilisez.

je voudrais utiliser strcmp sur les chaînes et strncmp sur la recherche de sous-chaînes.

0
user9455050

Il suffit de poster ici un cas d’utilisation anti-strncmp. Pensez au code suivant.

#include <stdio.h>
#include <dirent.h>

int main()
{
    //I want to list all files under current folder, include hidden files.
    DIR *dir;
    struct dirent *dp;
    char * file_name;
    dir = opendir(".");
    while ((dp=readdir(dir)) != NULL) {
        printf("debug: %s\n", dp->d_name);
        if ( !strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..") )
        //It doesn't work if you replace strcmp with strncmp here.
        //if ( !strncmp(dp->d_name, ".", 1) || !strncmp(dp->d_name, "..", 2) )  
        {
        } else {
            file_name = dp->d_name;
            printf("file_name: \"%s\"\n",file_name);
        }
    }
    closedir(dir);
    return 0;
}
0
user3099889