C ++ String->替换不按预期工作

时间:2014-12-24 17:16:01

标签: .net string c++-cli user-defined-functions str-replace

我正在尝试创建一个程序,在我拥有的宇宙模拟游戏中为行星生成疯狂的lib样式故事。它的设计使用户可以在.txt文件中输入故事模板,故事模板中的变量放在百分号内。该程序读取.txt文件,提取故事,查找变量,并使用适当的随机信息填充变量(目前,我只定义了两个变量)。

我遇到的问题是它不会替换故事中的变量,即使我调试它的所有尝试(正如您将在代码/输出中看到的)显示计算机生成适当的文本,并且识别该变量在文本中。

问题的实际行在“GetVar()”函数定义内的底部附近。

完整程序(减去控件初始化以缩短时间):

#pragma once
namespace SpaceEngineStoryTeller {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
    Form1(void) {
        InitializeComponent();
        //
        //TODO: Add the constructor code here
        //
    }
protected:
    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    ~Form1() {
        delete components;
    }
private:
    System::Windows::Forms::TabControl^  tabControl1;
    System::Windows::Forms::TabPage^  tabPage1;
    System::Windows::Forms::Label^  label4;
    System::Windows::Forms::Label^  label3;
    System::Windows::Forms::Label^  label2;
    System::Windows::Forms::Label^  label1;
    System::Windows::Forms::TabPage^  tabPage2;
    System::Windows::Forms::Label^  label7;
    System::Windows::Forms::Label^  label6;
    System::Windows::Forms::Label^  label5;
    System::Windows::Forms::ComboBox^  TemperatureBox;
    System::Windows::Forms::Label^  label11;
    System::Windows::Forms::TabPage^  tabPage3;
    System::Windows::Forms::RichTextBox^  ExportBox;
    System::Windows::Forms::Label^  label10;
    System::Windows::Forms::PictureBox^  pictureBox1;
    System::Windows::Forms::RichTextBox^  ImportBox;
    System::Windows::Forms::Label^  label9;
    System::Windows::Forms::RichTextBox^  StoryBox;
    System::Windows::Forms::Label^  label8;
    System::Windows::Forms::ComboBox^  LifeBox;
    System::Windows::Forms::Label^  label13;
    System::Windows::Forms::ComboBox^  TypeBox;
    System::Windows::Forms::Label^  label12;
    System::Windows::Forms::TextBox^  AtmosphereBox;
    System::Windows::Forms::Label^  label15;
    System::Windows::Forms::TextBox^  GravityBox;
    System::Windows::Forms::Label^  label14;
    System::Windows::Forms::Label^  label16;
    System::Windows::Forms::Button^  button1;
    System::Windows::Forms::CheckBox^  SubglacialCheck;
    System::Windows::Forms::CheckBox^  TerrestrialCheck;
    System::Windows::Forms::CheckBox^  MarineCheck;
    System::Windows::Forms::CheckBox^  FloatersCheck;
    System::Windows::Forms::PictureBox^  pictureBox3;
    System::Windows::Forms::PictureBox^  pictureBox2;
    /// <summary>
    /// Required designer variable.
    int StoriesCtr, SpaceRacesCtr, NonSpaceRacesCtr, varctr, RndHolder, ArrayLength, StoryLength;
    Random ^ Rnd;
    String^ path;
    static array<String^>^ var=gcnew array<String^>(65535);
    static array<String^>^ Stories=gcnew array<String^>(65535);
    static array<String^>^ subStory=gcnew array<String^>(65535);
    static array<String^>^ SpaceRaces=gcnew array<String^>(65535);
    static array<String^>^ NonSpaceRaces=gcnew array<String^>(65535);
    /// </summary>
    System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
private:
    void InitializeComponent(void) {
        //Omitted Code
    }
#pragma endregion
private:
    System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
        StoriesCtr=0;
        SpaceRacesCtr=0;
        NonSpaceRacesCtr=0;
        varctr=0;
        ArrayLength=0;
        Rnd=gcnew Random;
        path="C:\\Users\\Ben\\Documents\\Visual Studio 2012\\Projects\\SpaceEngine Story Teller\\Resources\\Stories.txt";
        StreamReader^ StoryReader = gcnew StreamReader(path, true);
        while(StoryReader->EndOfStream==false) {
            Stories[StoriesCtr]=StoryReader->ReadLine();
            StoriesCtr++;
        }
        StoryReader->Close();
        path="C:\\Users\\Ben\\Documents\\Visual Studio 2012\\Projects\\SpaceEngine Story Teller\\Resources\\SpaceRaces.txt";
        StreamReader^ SpaceRacesReader = gcnew StreamReader(path, true);
        while(SpaceRacesReader->EndOfStream==false) {
            SpaceRaces[SpaceRacesCtr]=SpaceRacesReader->ReadLine();
            SpaceRacesCtr++;
        }
        SpaceRacesReader->Close();
        path="C:\\Users\\Ben\\Documents\\Visual Studio 2012\\Projects\\SpaceEngine Story Teller\\Resources\\NonSpaceRaces.txt";
        StreamReader^ NonSpaceRacesReader = gcnew StreamReader(path, true);
        while(NonSpaceRacesReader->EndOfStream==false) {
            NonSpaceRaces[NonSpaceRacesCtr]=NonSpaceRacesReader->ReadLine();
            NonSpaceRacesCtr++;
        }
        NonSpaceRacesReader->Close();
        for(int i=0; i<StoriesCtr; i++) {
            StoryLength=Stories[i]->Length;
            GetVar(Stories[i]);
            this->StoryBox->Text+=Stories[i]+"\n";
        }
    }
    System::Void LifeBox_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) {
        if(this->LifeBox->SelectedIndex!=0) {
            this->TerrestrialCheck->Enabled=true;
            this->MarineCheck->Enabled=true;
            this->SubglacialCheck->Enabled=true;
            this->FloatersCheck->Enabled=true;
            this->label16->Enabled=true;
        } else {
            this->TerrestrialCheck->Enabled=false;
            this->MarineCheck->Enabled=false;
            this->SubglacialCheck->Enabled=false;
            this->FloatersCheck->Enabled=false;
            this->label16->Enabled=false;
        }
    }
    void GetVar(String^ str) {//Finds variables in story, and replaces them with random information
        for(int a=0; a<str->Length; a++)
            subStory[a]=str->Substring(a, 1);
        for(int b=0; b<str->Length; b++) {
            if(subStory[b]=="%") {//Beginning of variable
                for(int c=(b+1); c<str->Length; c++) {
                    if(subStory[c]=="%") {//End of variable
                        for(int d=(b+1); d<c; d++)//Generates variable from substrings
                            var[varctr]+=subStory[d];
                        for(int e=0; e<=varctr; e++) {//Replaces instances of variables in story with randomly generated terms.
                            if(var[e]=="SpaceRace") {
                                this->StoryBox->Text+="SpaceRace: ";
                                RndHolder=Rnd->Next()%GetArrayLength(SpaceRaces);
                                this->StoryBox->Text+=RndHolder+"\n";
                                var[varctr]=SpaceRaces[RndHolder];
                                this->StoryBox->Text+=var[varctr]+"\n";
                                if(str->Contains("%SpaceRace%"))
                                    this->StoryBox->Text+="Contains SpaceRace"+"\n";
                                str->Replace("%SpaceRace%", var[varctr]);//Problem line
                            } else if(var[e]=="NonSpaceRace") {
                                this->StoryBox->Text+="NonSpaceRace: ";
                                RndHolder=Rnd->Next()%GetArrayLength(NonSpaceRaces);
                                this->StoryBox->Text+=RndHolder+"\n";
                                var[varctr]=NonSpaceRaces[RndHolder];
                                this->StoryBox->Text+=var[varctr]+"\n";
                                if(str->Contains("%SpaceRace%"))
                                    this->StoryBox->Text+="Contains NonSpaceRace"+"\n";
                                str->Replace("%NonSpaceRace%", var[varctr]);//Problem line
                            }
                        }
                        varctr++;
                        break;
                    }
                }
            }
        }
    }
    int GetArrayLength(static array<String^>^ Array) {//Returns how many indexes of array are non-null
        for(int i=0; i<Array->Length; i++) {
            if(Array[i]==nullptr)
                return ArrayLength;
            ArrayLength++;
        }
        return ArrayLength;
    }
};
}

输出结果如何:

SpaceRace: 9
Chevin
Contains SpaceRace
NonSpaceRace: 536
Vors‎
Contains NonSpaceRace
%SpaceRace% is a space-faring species in Star Wars, and %NonSpaceRace% is a non-space-fairing species in Star Wars.

输出应该是什么样的:

SpaceRace: 9
Chevin
Contains SpaceRace
NonSpaceRace: 536
Vors‎
Contains NonSpaceRace
Chevin is a space-faring species in Star Wars, and Vors is a non-space-fairing species in Star Wars.

Stories.txt的内容(供参考):

%SpaceRace% is a space-faring species in Star Wars, and %NonSpaceRace% is a non-space-fairing species in Star Wars.

1 个答案:

答案 0 :(得分:0)

String.Replace返回带有替换值的新字符串,不进行就地替换。而不是:

str->Replace("%SpaceRace%", var[varctr]);

你需要

str = str->Replace("%SpaceRace%", var[varctr]);

有关详情,请参阅the MSDN entry for String.Replace