Brainfuck翻译奇怪的输出

问题描述 投票:0回答:1

我决定使用Borland的CppBuilder6在C ++中编写一个简单的Brainfuck IDE。我把它换成了RichEdit并让它看起来有点像记事本。然后我添加了TEdit用于输入,TMemo用于输出。经过一些测试后,我认为RichEdit在我的案例中使用的是不好的组件,我将其更改为TMemo。

在我的代码input = Edit2,code = Memo2,output = Memo1。我重写了两次,这个版本似乎最正确;我决定不使用指针(我考虑过它甚至编写了指针版本,不幸的是它没有用于简化我删除了指针)。

char *cells = (char*)calloc(65536,1); //Should i use malloc?
int cellp = 0;
void __fastcall BFIde::interpret() {
        char* pf = Memo2->Lines->Text.c_str(); //Weird output
        char* p = (char*)malloc(strlen(pf)+1);
        strcpy(p, pf); //Because pf is constant, i need to copy it into not constant string.
        int pp = 0;

        MessageBox(NULL,p,NULL,MB_OK); //To ensure that program is correct, but it ain't.

        while(p[pp]){
                switch(p[pp]){
                        case '>':
                                cellp++;
                                break;
                        case '<':
                                cellp--;
                                break;
                        case '+':
                                MessageBox(NULL, "Plus", NULL, MB_OK); //When executing test code, never gets shown.
                                cells[cellp]++;
                                break;
                        case '-':
                                cells[cellp]--;
                                break;
                        case '.':{ //It should look other, but I've replaced it to ensure that output is correct.
                                char arr[2]={cells[cellp],0};MessageBox(NULL, arr, NULL, MB_OK);}
                                break;
                        case ',': //Remove first character and pass it to program
                                if(Edit2->Text == "")cells[cellp] = 0;
                                else {cells[cellp] = Edit2->Text.c_str()[0];char* str;strcpy(str, Edit2->Text.c_str());Edit2->Text=str++;}
                                break;
                        case '[':{ //Propably works.
                                int bal = 1;
                                if (cells[cellp] == '\0') {
                                        do {
                                                pp++;
                                                if      (p[pp] == '[') bal++;
                                                else if (p[pp] == ']') bal--;
                                        } while ( bal != 0 );
                                }
                                break;
                        }
                        case ']':
                                int bal2 = 0;
                                do {
                                        if      (p[pp] == '[') bal2++;
                                        else if (p[pp] == ']') bal2--;
                                        pp--;
                                } while ( bal2 != 0 );
                                break;
                }
                pp++;
        }
        MessageBox(NULL, IntToStr(cellp).c_str(), NULL, MB_OK); //To check that something was parsed. Shows 0 everytime (not expected).
}

当我输入一些代码时,例如。 “+”。并执行此功能(通过按钮),这将显示一系列消息框。第一个:(第8行),第二个:0(第55行),没有更多的节目。预期的结果是写:第一个+.,第二个Plus,空第三个。我的代码中出错了什么?也许我错过了什么。

c++ interpreter vcl c++builder-6 brainfuck
1个回答
2
投票

您的代码中存在与内存相关的错误。 interpret()的第一行是指向一个临时的AnsiString指针,该指针随后立即被释放,因此随后的代码行操作时指向无效内存的悬空指针。同样,在','处理程序中,您试图将数据复制到未指向有效内存的未初始化指针。并且在访问cells[]数组时,您没有进行任何边界检查。

您的']'处理程序中也存在逻辑错误。您没有检查0的当前单元格数据以决定跳转到下一个指令,并且在查找开头'['时您没有正确地向后搜索。

尝试更像这样的东西:

static const int maxCells = 65536;

class BFIde : public TForm
{
__published:
    TEdit *Edit2;
    TMemo *Memo1;
    TMemo *Memo2;
    TButton *Button1;
    void __fastcall Button1(TObject *Sender);
private:
    char cells[maxCells];
    int cellp;
    char& cellData();
    void __fastcall interpret(const AnsiString &commands, AnsiString input);
public:
    __fastcall BFIde(TComponent *Owner);
};

__fastcall BFIde::BFIde(TComponent *Owner)
    : TForm(Owner)
{
}

char& __fastcall BFIde::cellData()
{
    if ((cellp < 0) or (cellp >= maxCells))
        throw Exception("Accessing cells out of bounds");
    return cells[cellp];
}

void __fastcall BFIde::interpret(const AnsiString &commands, AnsiString input)
{
    Memo1->Clear();

    memset(cells, 0, maxCells);
    cellp = 0;

    const char* start = commands.c_str();
    const char* p = start;

    while (*p)
    {
        switch (*p)
        {
            case '>':
                ++cellp;
                break;

            case '<':
                --cellp;
                break;

            case '+':
                cellData()++;
                break;

            case '-':
                cellData()--;
                break;

            case '.':
            {
                char ch = cellData();
                Memo1->SelStart = Memo1->GetTextLen();
                Memo1->SelLength = 0;
                Memo1->SelText = ch;
                break;
            }

            case ',':
            {
                char ch;
                if (input.Length() == 0) {
                    ch = '\0';
                }
                else {
                    ch = input[1];
                    input.Delete(1, 1);
                }
                cellData() = ch;
                break;
            }

            case '[':
            {
                if (cellData() == '\0')
                {
                    int bal = 1;
                    while (*++p)
                    {
                        if (*p == '[') {
                            ++bal;
                        }
                        else if (*p == ']')
                        {
                            if (--bal == 0)
                                break;
                        }
                    }
                    if (bal != 0)
                        throw Exception("Unbalanced loop");
                }
                break;
            }

            case ']':
            {
                if (cellData() != '\0')
                {
                    int bal = 1;
                    while (p > start)
                    {
                        --p;
                        if (*p == ']') {
                            ++bal;
                        }
                        else if (*p == '[')
                        {
                            if (--bal == 0)
                                break;
                        }
                    }
                    if (bal != 0)
                        throw Exception("Unbalanced loop");
                }
                break;
            }
        }

        ++p;
    }

    ShowMessage(cellp);
}

void __fastcall BFIde::Button1(TObject *Sender)
{
    interpret(Memo2->Lines->Text,  Edit2->Text);
}
© www.soinside.com 2019 - 2024. All rights reserved.