1

Skypeボットのメッセージループを実行しています。これは、メッセージを簡単にアドバタイズ/マスできることを意味します。ただし、ループ内の名文字列がクラス内の名前に置き換えられた後は、その名前のみが使用され、次のループで新しい名前が置き換えられることはありません。

コード:

if(listView2.SelectedItems.Count<=0)
    return;

string value="Hi %name%!";
string body="";

if(Program.InputBox("New Message", "Body of the message:", ref value)==DialogResult.OK) {
    body=value;
}

foreach(ListViewItem i in listView2.SelectedItems) {
    String rawID=i.SubItems[7].ToString();
    String[] splitID=rawID.Split('}');
    String[] ID=splitID[0].Split(new char[] { '{' });

    body=body.Replace("%handle%", SkypeUser.Users[Convert.ToInt32(ID[1])].Handle);
    body=body.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
    body=body.Replace("%status%", SkypeUser.Users[Convert.ToInt32(ID[1])].Status);
    body=body.Replace("%country%", SkypeUser.Users[Convert.ToInt32(ID[1])].Country);
    body=body.Replace("%mood%", SkypeUser.Users[Convert.ToInt32(ID[1])].Mood);
    body=body.Replace("%about%", SkypeUser.Users[Convert.ToInt32(ID[1])].About);

    if(!(body==String.Empty)) {
        skype.SendMessage(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle, body);
    }
}

Jim、Tim、Derpという名前の3人を選択すると、選択したリストの最初の人はJimです。を使用%name%した場合、Jimへのメッセージでは「Jim」に正しく置き換えられますが、TimとDerpへのメッセージにも%name%、名前が文字列に置き換えられる代わりに「Jim」が含まれます。


編集:

ループ内にvalue、およびifステートメントを配置することを知っています。bodyしかし、私はメッセージを入力する必要があるのは一度だけであることを望みます。それがマスメッセージの要点です。

4

5 に答える 5

2

次のステートメントは for ループ内にある必要があります。

            string value = "Hi %name%!";
            string body = "";
            if (Program.InputBox("New Message", "Body of the message:", ref value) == DialogResult.OK)
            {
                body = value;
            }
于 2013-02-25T12:19:42.810 に答える
2

初めてループを通過すると、%%プレースホルダーは効果的に破棄されます。あなたが一緒に行く場合:

body = "Hi %name%";

最初の繰り返しの後、次のようになります。

body = "Hi Jim";

ループが 2 回目に実行されると%name%、"Hi Jim" を検索しますが、置換するものが見つからず、文字列をそのままにして、"Hi Jim" を Derp に送信することになります。本体の元の値を変更することは避け、反復ごとに新しい変数を使用します。

foreach (ListViewItem i in listView2.SelectedItems)
{
   string userBody = body;
   ...
   userBody = userBody.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
   ...
}

また、C# のクラスは不変であることにも注意してください。つまりstring、ループ内の各文字列操作では、内容が変更された文字列の新しいインスタンスが作成され、以前の値は収集されるガベージとして残されます。重要な文字列操作を行う場合 (実際に行っている場合)StringBuilderは、文字列操作で使用するように設計されたクラスを調べてください。コードは次のようになります。

foreach (ListViewItem i in listView2.SelectedItems)
{
   StringBuilder userBodyBuilder = new StringBuilder(body);
   ...
   userBodyBuilder.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
   ...
}

このコードは元のコードよりも大幅に少ないメモリを浪費し、大幅に高速になるため、連絡先をより効率的にスパムすることができます:D

于 2013-02-25T12:20:41.173 に答える
0

初めてデータを置き換えたとき%XXX%("%name%"たとえば)、次にループを渡したときには、データがなくなっていると思います。

ループで新しい変数を使用します。

foreach[...]
{
  string currentBody = body;
  currentBody = body.Replace[...]
  [...]
}
于 2013-02-25T12:22:44.760 に答える
0

メッセージを送信した後、文字列を再度置き換えるだけです<3

あなたがコピーするための簡単なコード

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle, "%handle%");
}

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Name!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Name, "%name%");
}

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Status!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Status, "%status%");
}

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Country!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Country, "%country%");
}

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Mood!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Mood, "%mood%");
}

if(SkypeUser.Users[Convert.ToInt32(ID[1])].About!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].About, "%about%");
}
于 2013-02-25T12:44:43.863 に答える
-1

これは、ループ内の文字列本体を置き換えているためです。ループ内に一時変数を作成し、それに割り当てます。

于 2013-02-25T12:20:27.177 に答える