2016-07-23 8 views
2

ゲームエミュレータのプラグインで、入力メッセージにWebサイトのURLが含まれているかどうかを確認する前に、チャットメッセージからすべてのスペースを削除したいと考えています。Cの中のchar *配列から空白を削除

だから、私は(入力メッセージからスペースを削除)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___; 
} 

上記の作品、副作用があります。何が起こっているように見えるのは、入力メッセージが変更され、WebサイトのURLが含まれていない場合、メッセージのすべてのスペースが削除されていることです。例えば

、私が入力した場合:

Go]をwww.some-domain.com

に上記のgetのブロックされ、プレイヤーは賢いし、使用スペースもしようとするので、(この処理を行い):

www。 s o m m - d o m a i n。 C 0 mを

はしかし、あなたがこのような任意のウェブサイトのURLが含まれていない通常のメッセージを入力する場合:

こんにちは、お元気ですか?

それは次のようになってなってき:

こんにちは、howareyou?

これは、この行である:char* check_message = deblank(message); deblank関数は、元のメッセージを変更するように見えます。私はこの関数がスペースなしでオリジナルメッセージの新しいコピーを返すと思った。

元のinput messageの一時的なコピーを作成する方法はありますか?チェックを行う前に空白を削除しますか?

また、割り当てられたメモリを、入力の一時コピーにどのようにクリアするのですか?私はこれが周りに残ることを望んでいない。または、コードがスコープ内で実行を終了したら、Cはその一時char配列を自動的にクリアしますか?

答えて

1

いいえ、実際にはできません。

2つの解決策があります。 - 空白文字が何個あるかを最初にカウントするループがあります。割り当てが必要な分かります。

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とパッドと同じ大きさの文字列を割り当てます。

すなわち

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

こんにちは、説明とコードサンプルありがとうございます。これは現在期待どおりに動作しています。それは動作しますが、私は2つの警告があります。最初の1つは、次のコード行を指している** '<':符号付き/符号なし不一致** 'for(i = j = 0; i Latheesan

+0

えええええええええええええええええええええええええええええええええええええええええええええええええええええええ、もし彼らが 'size_t'でもあればベストだろう! (編集済み) – Ven

+0

2番目の質問:引数は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

関連する問題