Couper une chaîne en C

Brièvement:

Je recherche l’équivalent de Ssortingng.Trim in C de .NET en utilisant les Ssortingng.Trim win32 et C standard (en compilant avec MSVC2008, j’ai donc access à tous les éléments C ++ si nécessaire, mais j’essaie simplement de couper un caractère char* ).

Étant donné qu’il existe strchr , strtok et toutes sortes d’autres fonctions de chaîne, il devrait sûrement y avoir une fonction de rognage, ou une fonction qui peut être réutilisée …

Merci

Il n’existe pas de fonction de bibliothèque standard pour le faire, mais ce n’est pas trop difficile de lancer la vôtre. Il y a une question existante sur SO à propos de cette opération à laquelle on a répondu avec le code source.

Cela m’a donné envie d’écrire le mien – je n’ai pas aimé ceux qui avaient été fournis. Il me semble qu’il devrait y avoir 3 fonctions.

 char *lsortingm(char *s) { while(isspace(*s)) s++; return s; } char *rsortingm(char *s) { char* back = s + strlen(s); while(isspace(*--back)); *(back+1) = '\0'; return s; } char *sortingm(char *s) { return rsortingm(lsortingm(s)); } 

Vous pouvez utiliser la fonction standard isspace () dans ctype.h pour y parvenir. Comparez simplement les caractères de début et de fin de votre tableau de caractères jusqu’à ce que les deux extrémités ne disposent plus d’espaces.

“espaces” comprennent:

” (0x20) espace (SPC)

‘\ t’ (0x09) onglet horizontal (TAB)

‘\ n’ (0x0a) nouvelle ligne (LF)

‘\ v’ (0x0b) onglet vertical (VT)

‘\ f’ (0x0c) stream (FF)

‘\ r’ (0x0d) retour chariot (CR)

Bien qu’aucune fonction ne puisse effectuer tout le travail à votre place, vous devrez lancer votre propre solution pour comparer chaque côté du tableau de caractères donné de manière répétée jusqu’à ce qu’il ne rest plus d’espaces.

Modifier:

Puisque vous avez access au C ++, Boost a une implémentation précise qui vous simplifie la vie.

Surpris de voir de telles implémentations. J’ai l’habitude de couper comme ça:

 char *sortingm(char *s) { char *ptr; if (!s) return NULL; // handle NULL ssortingng if (!*s) return s; // handle empty ssortingng for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); --ptr); ptr[1] = '\0'; return s; } 

Il est rapide et fiable – me sert de nombreuses années.

 /* Function to remove white spaces on both sides of a ssortingng ie sortingm */ void sortingm (char *s) { int i; while (isspace (*s)) s++; // skip left side white spaces for (i = strlen (s) - 1; (isspace (s[i])); i--) ; // skip right side white spaces s[i + 1] = '\0'; printf ("%s\n", s); } 
 #include "stdafx.h" #include  #include  char* sortingm(char* input); int _tmain(int argc, _TCHAR* argv[]) { char sz1[]=" MQRFH "; char sz2[]=" MQRFH"; char sz3[]=" MQR FH"; char sz4[]="MQRFH "; char sz5[]="MQRFH"; char sz6[]="M"; char sz7[]="M "; char sz8[]=" M"; char sz9[]=""; char sz10[]=" "; printf("sz1:[%s] %d\n",sortingm(sz1), strlen(sz1)); printf("sz2:[%s] %d\n",sortingm(sz2), strlen(sz2)); printf("sz3:[%s] %d\n",sortingm(sz3), strlen(sz3)); printf("sz4:[%s] %d\n",sortingm(sz4), strlen(sz4)); printf("sz5:[%s] %d\n",sortingm(sz5), strlen(sz5)); printf("sz6:[%s] %d\n",sortingm(sz6), strlen(sz6)); printf("sz7:[%s] %d\n",sortingm(sz7), strlen(sz7)); printf("sz8:[%s] %d\n",sortingm(sz8), strlen(sz8)); printf("sz9:[%s] %d\n",sortingm(sz9), strlen(sz9)); printf("sz10:[%s] %d\n",sortingm(sz10), strlen(sz10)); return 0; } char *lsortingm(char *s) { while(isspace(*s)) s++; return s; } char *rsortingm(char *s) { char* back; int len = strlen(s); if(len == 0) return(s); back = s + len; while(isspace(*--back)); *(back+1) = '\0'; return s; } char *sortingm(char *s) { return rsortingm(lsortingm(s)); } 

Sortie:

 sz1:[MQRFH] 9 sz2:[MQRFH] 6 sz3:[MQR FH] 8 sz4:[MQRFH] 7 sz5:[MQRFH] 5 sz6:[M] 1 sz7:[M] 2 sz8:[M] 2 sz9:[] 0 sz10:[] 8 
 static inline void ut_sortingm(char * str) { char * start = str; char * end = start + strlen(str); while (--end >= start) { /* sortingm right */ if (!isspace(*end)) break; } *(++end) = '\0'; while (isspace(*start)) /* sortingm left */ start++; if (start != str) /* there is a ssortingng */ memmove(str, start, end - start + 1); } 

J’aime bien quand la valeur de retour est toujours égale à l’argument. De cette façon, si le tableau de chaînes a été alloué avec malloc() , il peut à nouveau être free() toute sécurité.

 /* Remove leading whitespaces */ char *lsortingm(char *const s) { size_t len; char *cur; if(s && *s) { len = strlen(s); cur = s; while(*cur && isspace(*cur)) ++cur, --len; if(s != cur) memmove(s, cur, len + 1); } return s; } /* Remove trailing whitespaces */ char *rsortingm(char *const s) { size_t len; char *cur; if(s && *s) { len = strlen(s); cur = s + len - 1; while(cur != s && isspace(*cur)) --cur, --len; cur[isspace(*cur) ? 0 : 1] = '\0'; } return s; } /* Remove leading and trailing whitespaces */ char *sortingm(char *const s) { rsortingm(s); // order matters lsortingm(s); return s; } 
 void lsortingm(char str[PATH_MAX]) { int i = 0, j = 0; char buf[PATH_MAX]; strcpy(buf, str); for(;str[i] == ' ';i++); for(;str[i] != '\0';i++,j++) buf[j] = str[i]; buf[j] = '\0'; strcpy(str, buf); } 

Que diriez-vous de cela … Il ne nécessite qu’une seule itération sur la chaîne (n’utilise pas strlen, qui itère sur la chaîne). Lorsque la fonction retourne, vous obtenez un pointeur sur le début de la chaîne coupée, qui est terminée par un zéro. La chaîne est coupée des espaces de la gauche (jusqu’à ce que le premier caractère soit trouvé). La chaîne est également coupée de tous les espaces à la fin du dernier caractère non-espace.

 char* sortingm(char* input) { char* start = input; while (isSpace(*start)) { //sortingm left start++; } char* ptr = start; char* end = start; while (*ptr++ != '\0') { //sortingm right if (!isSpace(*ptr)) { //only move end pointer if char isn't a space end = ptr; } } *end = '\0'; //terminate the sortingmmed ssortingng with a null return start; } bool isSpace(char c) { switch (c) { case ' ': case '\n': case '\t': case '\f': case '\r': return true; break; default: return false; break; } } 
 /* iMode 0:ALL, 1:Left, 2:Right*/ char* Trim(char* szStr,const char ch, int iMode) { if (szStr == NULL) return NULL; char szTmp[1024*10] = { 0x00 }; strcpy(szTmp, szStr); int iLen = strlen(szTmp); char* pStart = szTmp; char* pEnd = szTmp+iLen; int i; for(i = 0;i < iLen;i++){ if (szTmp[i] == ch && pStart == szTmp+i && iMode != 2) ++pStart; if (szTmp[iLen-i-1] == ch && pEnd == szTmp+iLen-i && iMode != 1) *(--pEnd) = '\0'; } strcpy(szStr, pStart); return szStr; } 

Voici mon implémentation, qui se comporte comme les fonctions de chaîne intégrées dans libc (c’est-à-dire qu’elle attend une chaîne c, elle la modifie et la renvoie à l’appelant).

Il coupe les espaces de début et décale les caractères restants vers la gauche, car il parsing la chaîne de gauche à droite. Il marque ensuite une nouvelle fin de chaîne et commence à l’parsingr en arrière, en remplaçant les espaces de fin par des \ 0 jusqu’à ce qu’il trouve un caractère non-espace ou le début de la chaîne. Je crois que ce sont les itérations minimales possibles pour cette tâche particulière.

 // ---------------------------------------------------------------------------- // sortingm leading & trailing spaces from ssortingng s (return modified ssortingng s) // alg: // - skip leading spaces, via cp1 // - shift remaining *cp1's to the left, via cp2 // - mark a new end of ssortingng // - replace trailing spaces with '\0', via cp2 // - return the sortingmmed s // char *s_sortingm(char *s) { char *cp1; // for parsing the whole s char *cp2; // for shifting & padding // skip leading spaces, shift remaining chars for (cp1=s; isspace(*cp1); cp1++ ) // skip leading spaces, via cp1 ; for (cp2=s; *cp1; cp1++, cp2++) // shift left remaining chars, via cp2 *cp2 = *cp1; *cp2-- = 0; // mark new end of ssortingng for s // replace trailing spaces with '\0' while ( cp2 > s && isspace(*cp2) ) *cp2-- = 0; // pad with '\0's return s; } 

Pas le meilleur moyen mais ça marche

 char* Trim(char* str) { int len = strlen(str); char* buff = new char[len]; int i = 0; memset(buff,0,len*sizeof(char)); do{ if(isspace(*str)) continue; buff[i] = *str; ++i; } while(*(++str) != '\0'); return buff; } 
 void inPlaceStrTrim(char* str) { int k = 0; int i = 0; for (i=0; str[i] != '\0';) { if (isspace(str[i])) { // we have got a space... k = i; for (int j=i; j 

La chose la plus simple à faire est une simple boucle. Je vais supposer que vous voulez que la chaîne coupée soit retournée sur place.

 char * strTrim(char * s){ int ix, jx; int len ; char * buf len = strlen(s); /* possibly should use strnlen */ buf = (char *) malloc(strlen(s)+1); for(ix=0, jx=0; ix < len; ix++){ if(!isspace(s[ix])) buf[jx++] = s[ix]; buf[jx] = '\0'; strncpy(s, buf, jx); /* always looks as far as the null, but who cares? */ free(buf); /* no good leak goes unpunished */ return s; /* modifies s in place *and* returns it for swank */ } 

Cela supprime également les blancs incorporés. Si Ssortingng.Trim ne le fait pas, il lui faut un peu plus de logique.