用C编写打印方法

用C编写打印方法,c,pointers,scheme,interpreter,C,Pointers,Scheme,Interpreter,我是C语言的新手,正在为Scheme做一个翻译。我试图获得一个合适的printList方法来遍历这个结构 该程序接收如下输入: (a(b)(c)) 并在内部表示为: [""][ ][ ]--> [""][ ][/] | | ["A"][/][/] [""][ ][ ]--> [""][ ][/] | |

我是C语言的新手,正在为Scheme做一个翻译。我试图获得一个合适的printList方法来遍历这个结构

该程序接收如下输入:

(a(b)(c))

并在内部表示为:

[""][ ][ ]-->  [""][ ][/]
     |              |              
   ["A"][/][/]     [""][ ][ ]-->  [""][ ][/]     
                        |              |                 
                      ["B"][/][/]    ["C"][/][/]
现在,我只想让程序接收输入,在内部生成适当的单元格结构并打印出单元格结构,从而得到

(a(b)(c))

最后

这是我的结构:

typedef struct conscell *List;

struct conscell {
char symbol;
struct conscell *first;
struct conscell *rest;

};


void printList(char token[20]){
    List current = S_Expression(token, 0);

     printf("(");

printf("First Value? %c \n", current->first->symbol);
printf("Second value? %c \n", current->rest->first->first->symbol);
printf("Third value? %c \n", current->rest->first->rest->first->symbol);


printf(")");

}
在main方法中,我获取第一个令牌并调用:

打印列表(令牌)

我再次测试了子列表的值,我认为它是有效的。但是,我需要一种方法来遍历整个结构。请再次查看我的打印列表代码。打印调用是我必须键入的,以手动获取(a(b c))列表值。所以我得到了这个输出:

第一价值?a

第一价值?b

第一价值?c

这正是我想要的,但我想要一种使用循环的方法,不管结构有多复杂,也在适当的地方添加括号,所以最后,我应该得到:

(a(b)(c))

与输入相同


有人能帮我一下吗?

列表的类型是struct conscell的指针,因此createList函数中的malloc()应该是sizeof(struct conscell):

指向结构的指针仅为8字节,而结构本身的大小为17(默认填充为24字节):


原始程序的数据类型有点奇怪;您希望能够描述一组不相交的数据,在这种情况下,联合可能就是您想要的。目前,cons单元格只有一个数据类型,这使得很难区分:

(a b c)

您现在使用的技巧是将符号数据视为单元格左右指针均为NULL的数据,但这使得无法表示:

(())
这正是当您有一个内容都为NULL的cons单元格时发生的情况

表示不相交数据集的一种方法是使用标记的不相交并集,如下所示:

enum SexpType {SYMBOL, CONS, NIL};

struct Sexp {
  enum SexpType type;
  union {
    char symbol;
    struct Cons *cons;
  };
};

struct Cons {
  struct Sexp *first;
  struct Sexp *rest;
};
printf("(");
printSexp(sexp->cons->first);
printf(" . ");
printSexp(sexp->cons->rest);
printf(")");
Sexp可以是
符号
CONS
、或
NIL
。根据其类型,我们将以不同的方式处理结构的联合部分

我们可能会包括一些助手,以便更容易地构建此类结构:

struct Sexp* newCons(struct Sexp* first, struct Sexp* rest) {
  struct Sexp* pair = malloc(sizeof(struct Sexp));
  pair->type = CONS;
  pair->cons = malloc(sizeof(struct Cons));
  pair->cons->first = first;
  pair->cons->rest = rest;
  return pair;
}

struct Sexp* newSymbol(char c) {
  struct Sexp* ch = malloc(sizeof(struct Sexp));
  ch->type = SYMBOL;
  ch->symbol = c;
  return ch;
}
一旦我们有了正确的数据表示,那么
printList
将是一个递归函数,根据类型标记进行调度:

void printSexp(struct Sexp* sexp) {
  switch (sexp->type) {
  case SYMBOL: 
    /* FIXME */
    break;
  case CONS:
    /* FIXME */
    break;
  case NIL:
    /* FIXME */
    break;
  }
}
每种情况都相当简单。要让
CONS
案例执行某些操作,我们可以尝试以下操作:

enum SexpType {SYMBOL, CONS, NIL};

struct Sexp {
  enum SexpType type;
  union {
    char symbol;
    struct Cons *cons;
  };
};

struct Cons {
  struct Sexp *first;
  struct Sexp *rest;
};
printf("(");
printSexp(sexp->cons->first);
printf(" . ");
printSexp(sexp->cons->rest);
printf(")");

我们递归调用打印机对的组件。但是,这可能不是我们想要的,因为它将所有内容都视为不正确的结构,您可能希望为常规列表做一些更好的事情。

列表的类型是struct conscell的指针,因此malloc的大小应为sizeof(struct conscell)…非常感谢您在修复此问题时提供的帮助。现在它更有意义了。您还可以查看更新后的问题,看看是否可以找到根本问题吗?@RehanRasool在如上所述修复分配大小后,您可能还需要插入程序中的内存泄漏
List
是指针类型,并且
temp=createList()紧跟其后的是
temp=local是两行短的直接内存泄漏。@WhozCraig很好。我只是在看createList()函数。@RehanRasool您也可以发布getToken()函数和程序的主要方法吗?函数S_表达式中的strcpy也有点令人担忧…@tanukisotware我认为这将是很多您可能不想了解的信息。getToken只获取输入行中的下一个字符串。例如,如果我输入:(abc)第一个strcpy(token,getToken)调用,则复制('到令牌。下次,它将'a'复制到令牌,下次将'b'复制到令牌等等。如果您仍然想看到它,我可以上传它。其次,现在作业不需要我处理内存丢失问题,所以我不担心。感谢您到目前为止的回复!