首页 > 解决方案 > C 语言中的 Brain**** 实现

问题描述

我正在尝试使用我本周制作的 Brainfuck 实现运行一个 hello world 程序,但我得到了一个奇怪的输出。

这是我要运行的 hello world 文件。

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.------- 
-.>>+.>++.

我已经将它保存到 hello.txt,并在程序的 main 函数中解析它。

输出是

1 -3 4 4 7 0 -1 7 10 4 -4 1 2

其中,当您添加 72 并转换为 character 时,会给出

I E L L O H G O R L D I J

所以看起来我缺少一些东西,即使它有点接近正确的解决方案。

但无论如何我会进入事物的结构,总体思路如下:

我们有两个“磁带”,一个程序要遵循,我标记为“已解析”,它有一个“附加”指针,还有一个要写入的空磁带,我标记为“mem”,它也有一个指针“附加”给它。我们还有一个结构列表,可以用来在括号位置之间跳转。

在 main 函数中,分为三个部分:首先我解析程序并将其存储在一个数组中。然后我运行这个解析并匹配括号,然后我开始brainfuck循环并将输出写入空数组,直到到达最后一个字符。

在brainfuck 循环中,当我们找到一个括号时,我们会遍历配对列表以找到它的匹配项,然后跳转到那个位置。

也许它有点笨拙,但我希望它是有道理的。

    #include <stdio.h>
    #include <stdlib.h>

    #define MAX 30000

    //input tape
    char parsed[MAX];
    char * ptr;

    //bracket matching
    struct bracketlinks{
        char * bracket_1;
        char * bracket_2;
    };
    struct bracketlinks * pairslist;
    int bracket_count;

    //output tape
    char mem[MAX] = {0};
    int * mptr;

    int main(){
        mptr = malloc(sizeof(int));

        //parse text file and make list of tokens
        FILE * parsecode;
        parsecode = fopen("helloworldbf.txt", "r");
        int count = 0;
        char buffer;
        while(!feof(parsecode)){
            buffer = fgetc(parsecode);
            if(buffer == 10){break;}
            if(buffer == 32){continue;}
            else{
                parsed[count] = buffer;
                if(buffer == 91 || buffer == 93){
                    bracket_count++;
                }
                count++;
            }
        }
        fclose(parsecode);

        pairslist = malloc(bracket_count * sizeof(char*));

        //creates array of structures which match brackets so we can perform memory jumps
        int reset_count;
        int list_counter = 0;
        for(int i = 0; i < count; i++){
            if(parsed[i] == '['){
                reset_count = 0;
                for(int j = 0; j < count - i + 1; j++){
                    if(parsed[i + j] == '['){reset_count++;}
                    if(parsed[i + j] == ']'){reset_count--;}
                    if(reset_count == 0){
                        struct bracketlinks new;
                        new.bracket_1 = &parsed[i];
                        new.bracket_2 = &parsed[i + j];
                        pairslist[list_counter] = new;
                        list_counter++;
                        break;
                    }
                    else{continue;}
                } 
            }
            else{continue;}
        }

        //runs through the input tape and performs operations on the output tape
        ptr = parsed;
        char final_token = ptr[count];
        while(ptr[0] != final_token){
            if(ptr[0] == '['){
                if(mem[mptr[0]]){++ptr;}
                if(!mem[mptr[0]]){
                    for(int i = 0; i < bracket_count/2; i++){
                        if(pairslist[i].bracket_1 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_2;
                        }
                        if(pairslist[i].bracket_2 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_1;
                        }
                        else{continue;}
                    }
                }
            }
            if(ptr[0] == ']'){
                if(!mem[mptr[0]]){
                    for(int i = 0; i < bracket_count/2; i++){
                        if(pairslist[i].bracket_1 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_2;
                        }
                        if(pairslist[i].bracket_2 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_1;
                        }
                        else{continue;}
                    }
                }
                if(mem[mptr[0]]){++ptr;}
                else{continue;}
            }
            if(ptr[0] == '+'){++ptr;++mem[mptr[0]];}
            if(ptr[0] == '-'){++ptr;--mem[mptr[0]];}
            if(ptr[0] == '>'){++ptr; mptr[0]++;}
            if(ptr[0] == '<'){mptr[0]--;++ptr;}
            if(ptr[0] == '.'){++ptr; printf("%c %d \n", mem[mptr[0]] + 72, mem[mptr[0]]);}
            else{continue;}
        }
        free(pairslist);
        free(mptr);
        return 0;
    }

任何帮助将不胜感激,

干杯..

标签: cdebuggingbrainfuck

解决方案


好的,这是主要错误的修复:基本上只需切换感叹号,不要太笨拙。

 if(ptr[0] == ']'){
            if(mem[mptr[0]]){
                for(int i = 0; i < bracket_count/2; i++){
                    if(pairslist[i].bracket_1 == &ptr[0]){
                        ptr = ++pairslist[i].bracket_2;
                    }
                    if(pairslist[i].bracket_2 == &ptr[0]){
                        ptr = ++pairslist[i].bracket_1;
                    }
                    else{continue;}
                }
            }
            if(!mem[mptr[0]]){++ptr;}
            else{continue;}
        }

仍在处理 !feof 的事情,但也会随之更新


推荐阅读