2010-09-09 3 views
2

Есть ли лучший/более простой способ создать строку \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

Для crissake, использование мангалов литералов: если (* PTR> = '@') ... –

+1

Берегитесь Schlemiel художника здесь, тоже: HTTP: // WWW .joelonsoftware.com/articles/fog0000000319.html –

+0

Вы должны заметить, что если вы хотите скомпилировать как C++ (и вы должны *), вы не сможете использовать переменную с именем 'new', и вам нужна команда cast to' char * 'после вызова malloc. –

ответ

5

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

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

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

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

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

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

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

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

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 
Смежные вопросы