Comment vérifier si une chaîne commence par une autre chaîne en C?

Y a-t-il quelque chose comme startsWith(str_a, str_b) dans la bibliothèque standard C?

Il devrait prendre des pointeurs vers deux chaînes qui se terminent par nullbytes, et me dire si le premier apparaît aussi complètement au début du second.

Exemples:

 "abc", "abcdef" -> true "abcdef", "abc" -> false "abd", "abdcef" -> true "abc", "abc" -> true 

Apparemment, il n’y a pas de fonction C standard pour cela. Alors:

 bool startsWith(const char *pre, const char *str) { size_t lenpre = strlen(pre), lenstr = strlen(str); return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0; } 

Notez que ce qui précède est beau et clair, mais si vous le faites en boucle serrée ou avec de très grandes chaînes, il risque de ne pas offrir les meilleures performances, car il parsing toute la longueur des deux chaînes ( strlen ). Des solutions comme celles de wj32 ou de Christoph peuvent offrir de meilleures performances (bien que ce commentaire sur la vectorisation dépasse mon c de C). Notez également la solution de Fred Foo qui évite les strlen sur str (il a raison, c'est inutile). Ce n'est important que pour les très grandes chaînes ou les utilisations répétées dans les boucles serrées, mais quand c'est important, c'est important.

Il n’y a pas de fonction standard pour cela, mais vous pouvez définir

 bool prefix(const char *pre, const char *str) { return strncmp(pre, str, strlen(pre)) == 0; } 

Nous n’avons pas à nous soucier du fait que str soit plus court que pre car selon le standard C (7.21.4.4/2):

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 désigné par s1 au tableau pointé par s2 . ”

J’irais probablement avec strncmp() , mais juste pour l’amusement d’une implémentation brute:

 _Bool starts_with(const char *ressortingct ssortingng, const char *ressortingct prefix) { while(*prefix) { if(*prefix++ != *ssortingng++) return 0; } return 1; } 

Je ne suis pas un expert en écriture de code élégant, mais …

 int prefix(const char *pre, const char *str) { char cp; char cs; if (!*pre) return 1; while ((cp = *pre++) && (cs = *str++)) { if (cp != cs) return 0; } if (!cs) return 0; return 1; } 

Utilisez la fonction strstr() . Stra == strstr(stra, strb)

Parce que j’ai exécuté la version acceptée et que j’avais un problème avec une très longue str, j’ai dû append la logique suivante:

 bool longEnough(const char *str, int min_length) { int length = 0; while (str[length] && length < min_length) length++; if (length == min_length) return true; return false; } bool startsWith(const char *pre, const char *str) { size_t lenpre = strlen(pre); return longEnough(str, lenpre) ? strncmp(str, pre, lenpre) == 0 : false; } 

Optimisé (v.2. – corrigé):

 uint32 startsWith( const void* prefix_, const void* str_ ) { uint8 _cp, _cs; const uint8* _pr = (uint8*) prefix_; const uint8* _str = (uint8*) str_; while ( ( _cs = *_str++ ) & ( _cp = *_pr++ ) ) { if ( _cp != _cs ) return 0; } return !_cp; } 

Optimisé:

 boolean StartsWith(char *s1, char *s2) { while (*s1++ == *s2++) { } return *s2 == 0; }