2016-07-23 7 views
2

Я работаю над плагином в C для игрового эмулятора, где я хотел бы удалить все пробелы из сообщения чата, прежде чем проверять, содержат ли входящие сообщения какие-либо URL-адреса веб-сайта.удалить пробелы из char * array в C

Итак, у меня есть эта функция, как это deblank (убрать пробелы из входного сообщения):

char* deblank(char* input) { 
    int i, j; 
    char *output = input; 
    for (i = 0, j = 0; i < strlen(input); i++, j++) { 
     if (input[i] != ' ') 
      output[j] = input[i]; 
     else 
      j--; 
    } 
    output[j] = 0; 
    return output; 
} 

Я использую его в моем плагине крючок, как это:

bool my_pc_process_chat_message(bool retVal___, struct map_session_data *sd, const char *message) { 
    if (retVal___ == true) { 
     char* check_message = deblank(message); 
     bool url_detected = (stristr(check_message, "://") || stristr(check_message, "www.") || stristr(check_message, "vvvvvv.") || stristr(check_message, "wvvw.")); 
     if (!url_detected) { 
      int len = sizeof(tld_list)/sizeof(tld_list[0]); 
      int i; 
      for (i = 0; i < len; ++i) { 
       if (stristr(check_message, tld_list[i])) { 
        url_detected = true; 
        break; 
       } 
      } 
     } 
     if (url_detected) { 
      clif->messagecolor_self(sd->fd, COLOR_RED, "Possible GM Impersonation Detected - you cannot type website URLs in chat."); 
      return false; 
     } 
    } 
    return retVal___; 
} 

Вышеуказанные работы, но есть побочный эффект. Похоже, что происходит то, что входное сообщение изменяется, и все пробелы из сообщения удаляются, когда он не содержит URL-адресов веб-сайта.

Например, если я напечатал:

Перейти к www.some-domain.com

выше прибудете заблокирован, поэтому делает это (когда игроки пытаются быть умными и использование пространства):

www. s o m e - d o m a i n. с м о

Однако, когда вы вводите нормальное сообщение, которое не содержит каких-либо адреса веб-сайтов, как это:

Здравствуйте, как поживаете?

Это становится превращена в следующем:

Здравствуйте, howareyou?

Это из этой строки: char* check_message = deblank(message); Функция deblank по-видимому, изменения исходного сообщения. Я думал, что функция вернет новую копию сообщения orignal без пробелов.

Есть ли способ сделать временную копию оригинала input message, удалить пробелы с этого места, прежде чем делать чек?

Также как очистить выделенную память от временной копии входного сигнала orignal? Я не хочу, чтобы это задерживалось. Или C автоматически очищает этот массив temp char после того, как код завершит его выполнение в области?

ответ

1

Нет, вы не можете этого сделать.

Существует два решения: - Зациклируйте строку в первый раз, чтобы подсчитать, сколько нет символов пробела, поэтому вы знаете, сколько вам нужно выделить.

int count_not_empty(const char *str) 
{ 
    int n = 0; 

    for (; *str; ++str) { 
    if (*str != ' ') n++; 
    } 
    return n + 1; // the +1 is for the nulbyte at the end 
} 
  • Выделяют строку, как большой, как тот, который вы хотите обрезать, и площадку с nulbytes в конце.

i.e.

char *copy_not_empty(const char *str) 
{ 
    size_t i; 
    size_t j; 
    char *new = malloc(strlen(str) + 1); 

    for (i = j = 0; i < strlen(str); ++i) 
    { 
    if (str[i] != ' ') 
     new[j++] = str[i]; 
    } 
    for (; j <= i; j++) 
    new[j] = 0; // pad with nulbytes 
    return new; 
} 

+0

Привет, спасибо за пояснение и образец кода. Сейчас это работает так, как ожидалось. Хотя это работает, у меня есть два предупреждения. Первый: ** '<': несоответствие подписи/без знака **, указывающее на эту строку кода: 'for (i = j = 0; i Latheesan

+0

Ух, да, 'strlen' возвращает' size_t', который является неподписанным, тогда как я объявлял 'i j' целыми числами. Было бы лучше, если бы они были «size_t»! (отредактировано) – Ven

+0

Для вашего второго вопроса: аргумент не объявлен как const, но может быть (добавлен сейчас) – Ven

0

кодекс нарушил договор.

const char *message указывает на данные, которые не должны быть изменены. deblank(message) попытался модифицировать. это -> неопределенное поведение.

bool my_pc_process_chat_message(..., const char *message) { 
    if (retVal___ == true) { 
    char* check_message = deblank(message); 

Предупреждающий предупреждающий компилятор предупреждает об этом - экономит ваше время.

Для получения более подробной информации и идей отправьте телефонный код на номер my_pc_process_chat_message().

+0

« warning enableD »?? –

+1

@ machine_1 fixedd. – chux