Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org
GNU C library включает в себя множество функций работы с символами . Они продекларированы в `ctype.h'. Следующие функции определяют тип символа по его числовому идентификатору :
 
 int islower (int c)
 int isupper (int c)
 int isalpha (int c)
 int isdigit (int c)
 int isalnum (int c)
 int isxdigit (int c)
 int ispunct (int c)
 int isspace (int c)
 int isblank (int c)
 
Функции с приставкой -to- производят конверсию :
 int tolower (int c)
 int toupper (int c)
 int toascii (int c)
 int _toupper (int c)
 int _tolower (int c)
 
GNU C library определяет строку как массив символов . Строковая переменная - это обычно указатель типа char * . Нулевой символ - это '\0' - стоит в конце такой строки . Для того , чтобы определить , достиг ли указатель конца строки , нужно написать
!*p или *p == '\0'
. Длина строки :
size_t strlen (const char *s)
Например
strlen ("hello, world")    => 12  
Или
 char string[32] = "hello, world";
 sizeof (string)=> 32
 strlen (string)=> 12
 char *ptr = string;
 sizeof (ptr) => 4
 
Следующая функция полезна тогда,когда строка не заканчивается на '\0'.
size_t strnlen (const char *s, size_t maxlen)
Следующая функция копирует определенное количество байт из одного места в другое и возвращает адрес пункта назначения копирования :
void * memcpy (void *restrict to, const void *restrict from, size_t size)
Следующая функция копирует определенное количество символов из одного места в другое
wchar_t * wmemcpy (wchar_t *restrict wto, const wchar_t *restruct wfrom, size_t size)
 
Следующая функция аналогична memcpy с той лишь разницей , что возвращает адрес назначения плюс длина скопированной строки :
void * mempcpy (void *restrict to, const void *restrict from, size_t size)
Аналогичная функция :
wchar_t * wmempcpy (wchar_t *restrict wto, const wchar_t *restrict wfrom, size_t size)
Копирует массив байт одного значения с :
void * memset (void *block, int c, size_t size)
Копирует массив символов
wchar_t * wmemset (wchar_t *block, wchar_t wc, size_t size)
Функция , аналогичная memcpy
char * strcpy (char *restrict to, const char *restrict from)
Следующий пример делает конкатенацию `foo' и `bar' в `foobar' с помощью stpcpy :

 #include < string.h>
 #include < stdio.h>
 int main (void)
 {
   char buffer[10];
   char *to = buffer;
   to = stpcpy (to, "foo");
   to = stpcpy (to, "bar");
   puts (buffer);
   return 0;
 }
 
Следующий пример на произвольную конкатенацию :
 char *
 concat (const char *str, ...)
 {
   va_list ap, ap2;
   size_t total = 1;
   const char *s;
   char *result;
   va_start (ap, str);
 /* Actually va_copy, but this is the name more gcc versions   understand.  */
   __va_copy (ap2, ap);
 /* Determine how much space we need.  */
   for (s = str; s != NULL; s = va_arg (ap, const char *))
    total += strlen (s);
    va_end (ap);
    result = (char *) malloc (total);
    if (result != NULL)
    {
     result[0] = '\0';
     /* Copy the strings.  */
    for (s = str; s != NULL; s = va_arg (ap2, const char *))
    strcat (result, s);
    }
    va_end (ap2);
    return result;
   }
 
А теперь сравните более эффективный вариант этого же кода :
 char *concat (const char *str, ...)
 {
   va_list ap;
   size_t allocated = 100;
   char *result = (char *) malloc (allocated);
   char *wp;
   if (allocated != NULL)
   {
     char *newp;
     va_start (ap, atr);
     wp = result;
     for (s = str; s != NULL; s = va_arg (ap, const char *))
   {
     size_t len = strlen (s);
   /* Resize the allocated memory if necessary.  */
    if (wp + len + 1 > result + allocated)
     {
       allocated = (allocated + len) * 2;
       newp = (char *) realloc (result, allocated);
       if (newp == NULL)
       {
       free (result);
       return NULL;
       }
     wp = newp + (wp - result);
     result = newp;
     }
     wp = mempcpy (wp, s, len);
     }
   /* Terminate the result string.  */
   *wp++ = '\0';
   /* Resize memory to the optimal size.  */
     newp = realloc (result, wp - result);
     if (newp != NULL)
           result = newp;
     va_end (ap);
     }
   return result;
  }
 
Следующий пример показывает применение strncpy и strncat
 #include < string.h>
 #include < stdio.h>
 #define SIZE 10
 static char buffer[SIZE];
 main ()
 {
   strncpy (buffer, "hello", SIZE);
   puts (buffer);
   strncat (buffer, ", world", SIZE - strlen (buffer) - 1);
   puts (buffer);
 }
 
Программа выводит
  hello
  hello, wo
Функции сравнения :
  strcmp ("hello", "hello")     => 0    /* These two strings are the same. */
  strcmp ("hello", "Hello")     => 32   /* Comparisons are case-sensitive. */
  strcmp ("hello", "world")     => -15  /* The character 'h' comes before 'w'. */
  strcmp ("hello", "hello, world")        => -44  
  strncmp ("hello", "hello, world", 5)    => 0    
  strncmp ("hello, world", "hello, stupid world!!!", 5)  => 0 
     
  strverscmp ("no digit", "no digit")  => 0    /* same behavior as strcmp. */
  strverscmp ("item#99", "item#100")   => <0   /* same prefix, but 99 < 100. */
  strverscmp ("alpha1", "alpha001")    => >0   
  strverscmp ("part1_f012", "part1_f01")  => >0   /* two fractional parts. */
  strverscmp ("foo.009", "foo.0")         => <0 
 
Поисковые функции :
  strchr ("hello, world", 'l')     => "llo, world"
  strchr ("hello, world", '?')     => NULL
  strrchr ("hello, world", 'l')    => "ld"
  
  strstr ("hello, world", "l")     => "llo, world"
  strstr ("hello, world", "wo")    => "world"
  strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz")   => 5
  strcspn ("hello, world", " \t\n,.;!?")    => 5
  strpbrk ("hello, world", " \t\n,.;!?")    => ", world"
  
Пример с разбиением строк с использованием strtok:
 #include < string.h>
 #include < stddef.h>
 const char string[] = "words separated by spaces -- and, punctuation!";
 const char delimiters[] = " .,;:!-";
 char *token, *cp;
 cp = strdupa (string);                /* Make writable copy.  */
 token = strtok (cp, delimiters);      /* token => "words" */
 token = strtok (NULL, delimiters);    /* token => "separated" */
 token = strtok (NULL, delimiters);    /* token => "by" */
 token = strtok (NULL, delimiters);    /* token => "spaces" */
 token = strtok (NULL, delimiters);    /* token => "and" */
 token = strtok (NULL, delimiters);    /* token => "punctuation" */
 token = strtok (NULL, delimiters);    /* token => NULL */
 
Аалогичный пример с использованием strsep
  #include < string.h>
  #include < stddef.h>
  const char string[] = "words separated by spaces -- and, punctuation!";
  const char delimiters[] = " .,;:!-";
  char *running;
  char *token;
   running = strdupa (string);
  token = strsep (&running, delimiters);    /* token => "words" */
  token = strsep (&running, delimiters);    /* token => "separated" */
  token = strsep (&running, delimiters);    /* token => "by" */
  token = strsep (&running, delimiters);    /* token => "spaces" */
  token = strsep (&running, delimiters);    /* token => "" */
  token = strsep (&running, delimiters);    /* token => "" */
  token = strsep (&running, delimiters);    /* token => "" */
  token = strsep (&running, delimiters);    /* token => "and" */
  token = strsep (&running, delimiters);    /* token => "" */
  token = strsep (&running, delimiters);    /* token => "punctuation" */
  token = strsep (&running, delimiters);    /* token => "" */
  token = strsep (&running, delimiters);    /* token => NULL */
  
Конвертация бинарных данных в символьные :
  char * l64a (long int n)
Пример ее использования :
  char * encode (const void *buf, size_t len)
  {
    /* We know in advance how long the buffer has to be. */
    unsigned char *in = (unsigned char *) buf;
    char *out = malloc (6 + ((len + 3) / 4) * 6 + 1);
    char *cp = out;
   /* Encode the length. */
   /* Using `htonl' is necessary so that the data can be
   decoded even on machines with different byte order. */
    cp = mempcpy (cp, l64a (htonl (len)), 6);
     while (len > 3)
     {
        unsigned long int n = *in++;
        n = (n << 8) | *in++;
        n = (n << 8) | *in++;
        n = (n << 8) | *in++;
       len -= 4;
       if (n)
       cp = mempcpy (cp, l64a (htonl (n)), 6);
       else
       /* `l64a' returns the empty string for n==0, so we 
       must generate its encoding ("......") by hand. */
       cp = stpcpy (cp, "......");
       }
      if (len > 0)
      {
       unsigned long int n = *in++;
       if (--len > 0)
       {
        n = (n << 8) | *in++;
        if (--len > 0)
        n = (n << 8) | *in;
       }
       memcpy (cp, l64a (htonl (n)), 6);
       cp += 6;
      }
    *cp = '\0';
    return out;
 	 } 
Следующая программа демонстрирует работу библиотеки < string.h >. Хочется сказать несколько слов о ней : к ее написанию приложили руки несколько людей , и теперь нам приходится это расхлебывать . Большинство функций возвращают либо NULL , либо указатель на строку . Если функция может вернуть NULL , нужно проверять возвращаемое значение и делать соответствующую обработку в этом случае .
 #include < string.h >
 #include < stdio.h >
 /* 	Written by James M. Rogers 	02 Feb 2002 */
 
 #define  MAX_STRING_LENGTH  17
 #define STATIC_STRING "This is a long string "
 
 main (){
 
     char  aa[10];
     char  ab[100];
     char  ac[1000];
     char  ad[10000];
 
     char *ba;
     char *bb;
     char *bc;
     char *bd;
     char *be;
 
     char string_a[17];
     char string_b[MAX_STRING_LENGTH];
     char *string_c;
     int string_length;
 
     int    x;
     size_t y;
 
 /* Examples */
 
     /* This reserves room for 16 characters and an end of string marker. */
 
 
     strcpy ( string_a, "This is a string" );
 printf("\n strcpy (string_a, \"This is a string\" ); \n string_a=%s \n",string_a);
 
   /* the following copies a string in that is too large. */
   /* it shouldn't work, but often does.  */
     strcpy ( string_a, "This is a long string" );
 printf("\n strcpy(string_a,\"This is a string\" );\n string_a = %s\n",string_a);
 
 
     strncpy ( string_b, "This is a long string", MAX_STRING_LENGTH );
     string_b[MAX_STRING_LENGTH-1] = '\000';
 printf("\n strcpy(string_b, \"This is a string\");\n string_b=%s \n",string_b);
     
 
 
     string_length = strlen(STATIC_STRING);
     
     if (!(string_c = (char *) malloc ( string_length ))){
        /* no memory left, die */
        exit (1);
     }
 
     strncpy( string_c,  STATIC_STRING, string_length);
     string_c[string_length] = '\000';
     printf("\n string_c = %s \n", string_c);
 
     /* do something with the string */
     free(string_c);
 
 
 /* Copy */
 
     printf ("\n* Copy \n");
 
   /* void  *memcpy(void *dest, const void *src, size_t n); */
 
     memcpy (aa, "test", 5);
     printf ("\n memcpy (aa, \"test\", 5) \n aa = \"%s\"\n", aa);
 
   /* void *memmove(void *dest, const void *src, size_t n); */
 
     memmove (ab, aa, 10);
     printf ("\n memmove (ab, aa, 10) \n ab = \"%s\"\n", ab);
 
   /* char *strncpy(char *dest, const char *src, size_t n); */
 
     strncpy (aa, "ghij", 5);
     printf ("\n strncpy (aa, \"ghij\", 5) \n aa = \"%s\"\n", aa);
 
   /* char  *strcpy(char *dest, const char *src); */
 
     strcpy (ab, "abcdef");
     printf ("\n strcpy (ab, \"abcdefg\") \n ab = \"%s\"\n", ab);
 
 
 /* Concat */
 
     printf ("\n* Concat \n");
 
   /* char *strcat(char *dest, const char *src); */
 
     strcat (ab, aa);
     printf ("\n strcat (ab, aa) \n ab = \"%s\"\n", ab);
 
   /* char *strncat(char *dest, const char *src, size_t n); */
 
     strncat (ab, aa, 3);
     printf ("\n strncat (ab, aa, 3) \n ab = \"%s\"\n", ab);
 
 
 /* Compare */
 
     printf ("\n* Compare \n");
 
   /* int memcmp(const void *s1, const void *s2, size_t n); */
 
     x = memcmp("b", "abc", 1);
     printf ("\n x = memcmp(\"b\", \"abc\", 1) \n x = %d \n", x);
     
     x = memcmp("b", "bcd", 1);
     printf ("\n x = memcmp(\"b\", \"bcd\", 1) \n x = %d \n", x);
     
     x = memcmp("b", "cde", 1);
     printf ("\n x = memcmp(\"b\", \"cde\", 1) \n x = %d \n", x);
     
     x = memcmp("b", "b\0cd", 100);
     printf ("\n x = memcmp(\"b\", \"b\\0cd\", 100) \n x = %d \n", x);
     
   /* int strncmp(const char *s1, const char *s2, size_t n); */
 
     x = strncmp("b", "abc", 1);
     printf ("\n\n x = strncmp(\"b\", \"abc\", 1) \n x = %d \n", x);
     
     x = strncmp("b", "bcd", 1);
     printf ("\n x = strncmp(\"b\", \"bcd\", 1) \n x = %d \n", x);
     
     x = strncmp("b", "cde", 1);
     printf ("\n x = strncmp(\"b\", \"cde\", 1) \n x = %d \n", x);
     
     x = strncmp("b", "b\0cd", 100);
     printf ("\n x = strncmp(\"b\", \"b\\0cd\", 100) \n x = %d \n", x);
     
   /* int strcmp(const char *s1, const char *s2); */
 
     x = strcmp("b", "abc");
     printf ("\n\n x = strcmp(\"b\", \"abc\") \n x = %d \n", x);
     
     x = strcmp("b", "a");
     printf ("\n x = strcmp(\"b\", \"a\") \n x = %d \n", x);
     
     x = strcmp("b", "bcd");
     printf ("\n x = strcmp(\"b\", \"bcd\") \n x = %d \n", x);
     
     x = strcmp("b", "b");
     printf ("\n x = strcmp(\"b\", \"b\") \n x = %d \n", x);
     
     x = strcmp("b", "cde");
     printf ("\n x = strcmp(\"b\", \"cde\") \n x = %d \n", x);
     
     x = strcmp("b", "c");
     printf ("\n x = strcmp(\"b\", \"c\") \n x = %d \n", x);
     
     x = strcmp("b", "b\0cd");
     printf ("\n x = strcmp(\"b\", \"b\\0cd\") \n x = %d \n", x);
     
   /* int strcoll(const char *s1, const char *s2); */
 
     x = strcoll("b", "a");
     printf ("\n\n x = strcoll(\"b\", \"abc\") \n x = %d \n", x);
     
     x = strcoll("b", "b");
     printf ("\n x = strcoll(\"b\", \"b\") \n x = %d \n", x);
     
     x = strcoll("b", "c");
     printf ("\n x = strcoll(\"b\", \"cde\") \n x = %d \n", x);
     
     x = strcoll("b", "b\0cd");
     printf ("\n x = strcoll(\"b\", \"b\\0cd\") \n x = %d \n", x);
     
   /* size_t strxfrm(const char *s1, const char *s2, size_t n); */
 
     strncpy (ac, "abcdefghijklmnopqrstuvwxyz", 27);
     strncpy (aa, "efghijklmonp", 13);
 
     printf ("\n ac = %s \n", ac);
     printf ("\n aa = %s \n", aa);
     
     y = strxfrm(ac, aa, 27);
     printf ("\n y = strxfrm(ac, aa, 27) \n y = %d \n ac = \"%s\"\n", y, ac);
 
 
 /* Search */
 
     printf ("\n* Search \n");
 
   /* void *memchr(const void *s, int c, size_t n); */
 
     ba = memchr (ab, 'd', 10);
     printf ("\n ba = memchr(%s, 'd', 10) \n ba = \"%s\" \n ", ab, ba);
 
   /* size_t *strcspn(const char *s, const char *reject); */
 
     y = strcspn (ab, "dgh");
 printf("\n strcspn (\"%s\",\"dgh\")\n y = %d \n ab[%d] = %s \n",ab,y,y,&ab[y]);
     
   /* size_t *strspn(const char *s, const char *accept); */
 
  y = strspn (ab, "abcdef");
  printf("\n strspn(\"%s\",\"abcdef\")\n y=%d\n ab[%d]=%s \n",ab,y,y,&ab[y]);
     
   /* char *strpbrk(const char *s, const char *accept); */
 
     ba = strpbrk(ab, "cde");
     printf ("\n strpspn (\"%s\", \"cde\")  \n ba=%s \n",ab,ba);
 
   /* char *strchr(const char *s, int c); */
 
     ba = strchr (ab, 'h');
     printf ("\n ba = strchr(%s, 'h') \n ba = \"%s\" \n ", ab, ba);
 
   /* char *strrchr(const char *s, int c); */
 
     ba = strrchr (ab, 'h');
     printf ("\n ba = strrchr(%s, 'h') \n ba = \"%s\" \n ", ab, ba);
 
   /* char *strstr(const char *s, const char *substring); */
 
     ba = strstr (ab, "hij");
     printf ("\n ba = strchr(%s, 'hij') \n ba = \"%s\" \n ", ab, ba);
 
     ba = strstr (ab, "ghig");
     printf ("\n ba = strchr(%s, 'ghij') \n ba = \"%s\" \n ", ab, ba);
 
   /* char *strtok(char *s, const char *delim); */
 
     strcpy(ad, "This is an example sentence.");
     printf("\n strcpy(ad, \"This is an example sentence.\") \n"); 
 
     bb = strtok(ad, " ");
     while (bb) {
         printf ("  bb = \"%s\"\n", bb);
         bb = strtok(NULL, " ");
     }
         
 
 /* Misc */
 
     printf ("\n* Misc \n");
 
   /* void *memset(void *s, int c, size_t n); */
 
     memset(ac, 'a', 1000);
     ac[999] = '\0';
     printf ("\n memset(ac, 'a', 1000); \n ac[999] = '\\0'; \n ac = \"%s\" \n", ac);
 
   /* char *strerror(int errnum); */
 
     printf ("\n strerror(5) = %s \n", strerror (5));
 
   /* size_t *strlen(const char *s); */
 
     y = strlen(ac);
     printf("\n y = strlen(ac); \n y = %d \n", y);
 
 /* Non Portable */
 
     printf ("\n* Non Portable \n");
 
   /* int strcasecmp(const char *s1, const char *s2); */
 
     x = strcasecmp("b", "ABC");
     printf ("\n\n x = strcasecmp(\"b\", \"ABC\") \n x = %d \n", x);
 
     x = strcasecmp("b", "A");
     printf ("\n x = strcasecmp(\"b\", \"A\") \n x = %d \n", x);
 
     x = strcasecmp("b", "BCD");
     printf ("\n x = strcasecmp(\"b\", \"BCD\") \n x = %d \n", x);
 
     x = strcasecmp("b", "B");
     printf ("\n x = strcasecmp(\"b\", \"B\") \n x = %d \n", x);
 
     x = strcasecmp("b", "CDE");
     printf ("\n x = strcasecmp(\"b\", \"CDE\") \n x = %d \n", x);
 
     x = strcasecmp("b", "C");
     printf ("\n x = strcasecmp(\"b\", \"C\") \n x = %d \n", x);
 
     x = strcasecmp("b", "B\0CD");
     printf ("\n x = strcasecmp(\"b\", \"B\\0CD\") \n x = %d \n", x);
 
   /* int strncasecmp(const char *s1, const char *s2, size_t n); */
 
     x = strncasecmp("b", "ABC", 1);
     printf ("\n\n x = strncasecmp(\"b\", \"ABC\", 1) \n x = %d \n", x);
 
     x = strncasecmp("b", "BCD", 1);
     printf ("\n x = strncasecmp(\"b\", \"BCD\", 1) \n x = %d \n", x);
 
     x = strncasecmp("b", "CDE", 1);
     printf ("\n x = strncasecmp(\"b\", \"CDE\", 1) \n x = %d \n", x);
 
     x = strncasecmp("b", "B\0CD", 100);
     printf ("\n x = strncasecmp(\"b\", \"B\\0CD\", 100) \n x = %d \n", x);
 
   /* char *strdup(const char *s); */
 
     ba = strdup ("Test of strdup");
     printf("\n ba = strdup (\"Test of strdup\"); \n ba = %s \n", ba);
 
   /* char *strfry(char *string); */
 
     strfry(ba);
     printf("\n strfry (ba); \n ba = %s \n", ba);
     free (ba);
 
   /* char *strsep(char **stringp, const char *delim); */
 
     strcpy(ad, "This is a second example sentence.");
     printf("\n strcpy(ad, \"%s\") \n", ad); 
 
     ba = ad;
 
     bb = strsep(&ba, " ");
     while (bb) {
         printf ("  bb = \"%s\"\n", bb);
         bb = strsep(&ba, " ");
     }
     
     printf ("\n ad == %s\n", ad);
     printf ("\n");
 
   /* char *index(const char *s, int c); */
   /* use strchr instead, it is the same function, only portable */
 
   /* char *rindex(const char *s, int c); */
   /* use strrchr instead, it is the same function, only portable */
 
 }
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье