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,那么所选列表中的第一个人就是 Jim。如果我使用%name%,它将在给 Jim 的消息中正确替换为“Jim”,但给 Tim 和 Derp 的消息也将包含“Jim”,而不是字符串替换%name%为他们的名字。


编辑:

我知道在循环中放置valuebodyif 语句;但我希望只需要输入一次消息。这就是大众信息的全部意义所在。

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

当循环第二次运行时,它%name%在“Hi Jim”中搜索,没有找到要替换的内容,不理会字符串,最终将“Hi Jim”发送给 Derp。避免修改 body 的原始值,并在每次迭代中使用一个新的变量:

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

另请注意,stringC# 中的类是不可变的,这意味着循环中的每个字符串操作都会创建一个具有修改内容的字符串的新实例,并将先前的值作为垃圾进行收集。如果您进行重要的字符串操作(并且您确实这样做了),请查看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 回答