Search code examples
c++c++builder-6

Delete from S first occurrence of a combination of 'red'


I have problems with rewriting code to Builder c++ 6 format. So the tasks are as follows:

  1. Delete from S first occurrence of a combination of 'red'
  2. After first combination 'th' paste 'e'
  3. Copy 5 symbols to Х from S and paste them after the 6th member(have problems with solving)
  4. Delete all "." and "," from S

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    AnsiString S = Edit1->Text;
    AnsiString X = Edit2->Text;
    string str;
    
    //Delete from S first occurrence of a combination of 'red'
    str = "red";
    std::size_t pos = S.find(str);
    if(pos != std::string::npos){
        S.replace(pos, str.length(), "");
    }
    
    //After first combination 'th' paste 'e'
    str = "th";
    pos = S.find(str);
    if(pos != std::string::npos){
        S.insert(pos + str.length(), "e");
    }
    
    //Copy 5 symbols to Х from S and paste them after the 6th member
    str = 6;
    pos = S.find(str);
    if(pos != std::string::npos){
        X = S.substr(pos + str.length(), 5);
    }
    
    //Delete all points and comas
    for(int i=1;i<s.Length();i++){
    if(s[i]=='.')s.Delete(i,1);
    }
    for(int i=1;i<s.Length();i++){
    if(s[i]==',')s.Delete(i,1);
    }
    Label1->Caption=S;
    Label2->Caption=X;
    }
    

Solution

  • You are mixing AnsiString and std::string logic together (or maybe you are migrating from std::string and do not know how to rewrite for AnsiString?). find(), replace(), insert(), length(), and substr() are all std::string methods. The AnsiString equivalents are Pos(), Delete(), Insert(), Length(), and SubString().

    There is no reason to mix the two string types together in the same function. Pick one or the other.

    Also, your two loops to delete periods/commas are broken. You are ignoring the last character in the string, and you skip a character every time you delete a character. So, either fix the loops, or you can just replace them with C++Builder's StringReplace() function instead.

    If you want to re-use your existing std::string-based code, you can do that. You do not have to use AnsiString:

    #include <string>
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        std::string S = Edit1->Text.c_str();
        std::string X = Edit2->Text.c_str();
        std::string str;
    
        //Delete from S first occurrence of a combination of 'red'
        str = "red";
        std::size_t pos = S.find(str);
        if (pos != std::string::npos){
            S.replace(pos, str.length(), "");
        }
    
        //After first combination 'th' paste 'e'
        str = "th";
        pos = S.find(str);
        if (pos != std::string::npos){
            S.insert(pos + str.length(), "e");
        }
    
        //Copy 5 symbols to Х from S and paste them after the 6th member
        str = "6";
        pos = S.find(str);
        if (pos != std::string::npos){
            X = S.substr(pos + str.length(), 5);
        }
    
        //Delete all points and comas
        pos = S.find_first_of(".,");
        while (pos != std::string::npos) {
            s.erase(pos, 1);
            pos = S.find_first_of(".,", pos);
        }
    
        Label1->Caption = S.c_str();
        Label2->Caption = X.c_str();
    }
    

    However, since you are interacting with VCL components, it might make sense to rewrite the code to use AnsiString instead (or better, System::String, in case you ever migrate the code to a modern C++Builder version):

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        System::String S = Edit1->Text;
        System::String X = Edit2->Text;
        System::String str;
    
        //Delete from S first occurrence of a combination of 'red'
        str = "red";
        int pos = S.Pos(str);
        if (pos != 0) {
            S.Delete(pos, str.Length());
        }
    
        //After first combination 'th' paste 'e'
        str = "th";
        pos = S.Pos(str);
        if (pos != 0) {
            S.Insert(pos + str.Length(), "e");
        }
    
        //Copy 5 symbols to Х from S and paste them after the 6th member
        str = 6;
        pos = S.Pos(str);
        if (pos != 0) {
            X = S.SubString(pos + str.Length(), 5);
        }
    
        //Delete all points and comas
        S = StringReplace(S, ".", "", TReplaceFlags() << rfReplaceAll);
        S = StringReplace(S, ",", "", TReplaceFlags() << rfReplaceAll);
    
        Label1->Caption = S;
        Label2->Caption = X;
    }