Более простой способ создания буквенно-цифровой + '_' строки из существующей строки? - PullRequest
2 голосов
/ 09 сентября 2010

Есть ли лучший / более простой способ создать \w+ строку из существующей строки?

 char *FixName(char *name)
 {
     char *ptr, tmp;
     char *new = malloc(strlen(name)+1);
     sprintf(new, "str_");
     for (ptr = name + 4; *ptr; ptr++)
     {
         if ((*ptr >= '0' && *ptr <= '9') ||
             (*ptr >= 'A' && *ptr <= 'Z') ||
             (*ptr >= 'a' && *ptr <= 'z') ||
             *ptr == '_')
         {
             tmp = *(ptr+1);
             *(ptr+1) = '\0';
             strcat(new, ptr);
             *(ptr+1) = tmp;
         }
     }
     free(name);
     return new;
 }

 // USAGE:
 //char *j = strdup("str_[](1.00)");
 //printf("J: %s\n", j);
 //j = FixName(j);
 //printf("J: %s\n", j);
 //free(j);
 // OUTPUT:
 //J: str_[](1.00)
 //J: str_100

Спасибо за комментарии, новая функция:

  void FixName(char *name)
  {
      char *ptr;
      unsigned short count = strlen("str_");
      for (ptr = name + count; *ptr; ptr++)
      {
          if ((*ptr >= '0' && *ptr <= '9') ||
              (*ptr >= 'A' && *ptr <= 'Z') ||
              (*ptr >= 'a' && *ptr <= 'z') ||
              *ptr == '_')
          {
              *(name+count) = *ptr;
              count++;
          }
      }
      *(name+count) = '\0';
  }

Ответы [ 2 ]

5 голосов
/ 09 сентября 2010

Одна вещь, которую вы можете сделать, чтобы сразу сделать код более понятным, - это использовать символьные литералы:

if ((*ptr >= '0' && *ptr <= '9') ||
    (*ptr >= 'A' && *ptr <= 'Z') ||
    (*ptr >= 'a' && *ptr <= 'z') ||
    *ptr == '_')

Лучшее решение - использовать isalnum .

if (isalnum(*ptr) || *ptr == '_')

Имейте в виду, что разные локали могут считать разные символы буквенно-цифровыми.

Еще несколько проблем с вашим кодом:

  • Вы можете определить необходимый размер строки, прежде чем выделять для нее память, чтобы избежать перераспределения.
  • Вы можете построить результат, не используя strcat, удерживая указатель там, где вы уже достигли.
  • Мне не нравится этот вызов free внутри функции. Вы не можете быть уверены, что строка, переданная в качестве параметра, была выделена с помощью malloc.
1 голос
/ 09 сентября 2010

Добавление к ответу Марка:

sprintf возвращает количество написанных им символов.Вы можете использовать это как:

    count = sprintf(new, "str_");
    for (ptr = name + 4; *ptr; ptr++) {

            if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'Z') ||
                (*ptr >= 'a' && *ptr <= 'z') || *ptr == '_')
            {
                    *(new+count) = *ptr;
                    count++;
            }
    }
    *(new+count) = 0; // terminating null char
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...