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"));
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.
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.
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.
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;
}