2016-07-23 16 views
2

Ich arbeite an einem Plugin in C für einen Spiele-Emulator, wo ich alle Leerzeichen aus Chat-Nachricht entfernen möchten, bevor Sie überprüfen, ob die Eingabe Nachrichten Website-URLs enthalten. SoEntfernen von Leerzeichen aus Char * Array in C

, ich habe diese Funktion so zu deblank (Leerzeichen entfernen von Eingangsnachricht):

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; 
} 

Ich benutze es in meinem Plugin Haken wie folgt aus:

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___; 
} 

Die oben genannten Arbeiten, aber es gibt einen Nebeneffekt. Es scheint, dass die Eingabe-Nachricht geändert wird und alle Leerzeichen aus der Nachricht entfernt werden, wenn sie keine Website-URLs enthält.

Zum Beispiel, wenn ich getippt:

Zum www.some-domain.com

Die blockierte die oben erhalten, also tut dies (wenn Spieler versuchen, klug und Nutzung Räume zu sein):

www. S o m e - d o m a n n. c o m

Wenn Sie jedoch eine normale Nachricht eingeben, die keine Website-URLs wie folgt enthält:

Hallo, wie geht es dir?

Es verwandelt in die folgenden:

Hallo, HowAreYou?

Dies ist wegen dieser Zeile: char* check_message = deblank(message); Die deblank Funktion erscheint die ursprüngliche Nachricht modifiziert werden. Ich dachte, die Funktion würde eine neue Kopie der ursprünglichen Nachricht ohne Leerzeichen zurückgeben.

Gibt es eine Möglichkeit, eine temporäre Kopie des Originals input message zu erstellen, entfernen Sie Leerzeichen davon, bevor Sie meine Überprüfung durchführen?

Wie löschen Sie außerdem den zugewiesenen Speicher für die temporäre Kopie des ursprünglichen Eingangs? Ich möchte nicht, dass das so bleibt. Oder löscht C automatisch das Array "temp char", sobald der Code die Ausführung im Bereich abgeschlossen hat?

Antwort

1

Nein, das kann man eigentlich nicht machen.

Es gibt zwei Lösungen: - Schleife die Zeichenfolge ein erstes Mal, um zu zählen, wie viele Nicht-Leerzeichen Zeichen gibt es, so dass Sie wissen, wie viel Sie zuordnen müssen.

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 
} 
  • Vergeben Sie einen String so groß wie die, die Sie und Pad mit nulbytes am Ende trimmen wollen.

, d.h.

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

Hallo, danke für die Erklärung und das Codebeispiel. Dies funktioniert jetzt wie erwartet. Obwohl es funktioniert, habe ich zwei Warnungen. Erster: ** '<': Vorzeichen/Unsigned Mismatch ** was auf diese Codezeile zeigt: 'für (i = j = 0; i Latheesan

+0

uh, yeah, 'strlen' gibt eine' size_t' zurück, die vorzeichenlos ist, während ich 'i j' als Ganzzahlen deklarierte. Es wäre am besten, wenn sie auch "size_t" wären! (bearbeitet) – Ven

+0

Für Ihre zweite Frage: Das Argument ist nicht als const deklariert, könnte aber (jetzt hinzugefügt) – Ven

0

brach-Code, den Vertrag.

const char *message verweist auf Daten, die nicht geändert werden sollten. deblank(message) versucht zu modifizieren. es -> undefiniertes Verhalten.

Ein ordnungsgemäß Warnung aktiviert Compiler würde davor warnen - spart Ihnen Zeit.

Für weitere Details und Ideen, geben Sie den Anrufcode an my_pc_process_chat_message().

+0

"warning enableD" ?? –

+1

@ Maschine_1 behoben. – chux