【问题标题】:Printing the structure of n-ary array in C在 C 中打印 n 元数组的结构
【发布时间】:2018-02-22 00:06:41
【问题描述】:

我的 c 课程作业是将菜单实现为 ​​n 叉树。我必须创建一个struct,用数据填充它并打印数据。 尽管创建结构和填充相对容易,但我发现打印的困难。我的目标是以这种方式打印结构:

  1 File
      1.1 Open
      1.2 Save As
      1.3 Save as Other
         1.3.1 Text
         1.3.2 Word or Excel Online
      1.4 Send File
         1.4.1 Attach to Email
         1.4.2 Send & Track
      1.5 Close

我的挣扎是我找不到如何: a) 在每个孩子之后添加空格。 b) 为孩子的每个孩子添加数字。

我的结构是这样的:

typedef struct node
{
    long nodeID;
    long parentNodeID;
    char name[100];
    struct node *next;
    struct node *child;
} node;

我的失败尝试:

void printMenu(node* root){
    if(root == NULL) {
        fprintf(stderr, "Root has not been initialised");
        exit(1);
    }
    if(root->parentNodeID == 0){
        printf("%ld %s",root -> nodeID,root -> name);
        fflush(stdout);
        printMenu(root->child);
    }
    if(root->child){
        printf("%6ld.%ld %s",root->parentNodeID,root->nodeID - 1,root->name);
        fflush(stdout);
        printMenu(root->child);
    }



    printf("%5ld.%ld %s",root->parentNodeID,root->nodeID - 1,root->name);
    fflush(stdout);
    printMenu(root -> next);

}

请发送帮助:(

【问题讨论】:

标签: c


【解决方案1】:

我建议使用递归。下面是一个如何工作的编码示例。您需要以从 0 开始的间距调用此函数。这还假定 parentID 是具有先前父 ID 的适当 ID。

void printMenu(node* root, int spacing) {
  if(root == NULL) {
    return;
  }
  else {
    for(int i =0; i < spacing; i++)  {
        printf(' ');
    }
    printf("%d.%d %s", root->parentNodeID, root->nodeID, root->name);
    for(int i =0; i< sizeof(root->child); i++) {
        printNodes(root->child[i], spacing+1);
    }
  }
}

【讨论】:

    【解决方案2】:

    而不是long parentNodeID,使用指向父节点的指针:

    typedef struct node
    {
        struct node *parent;
        struct node *next;
        struct node *child;
        char        *name;
        long         id;
    } node;
    

    根级节点(例如File)有NULL 父级。

    这使您可以使用简单的递归函数来打印 ID。唯一的技巧是你需要在打印之前递归:

    void print_path(FILE *out, node *to)
    {
        if (to->parent) {
            /* Non-root nodes */
            print_path(out, to->parent);
            fprintf(out, ".%ld", to->id);
        } else
            /* Root nodes */
            fprintf(out, "%ld", to->id);
    }
    

    有了这个,递归打印菜单很容易:

    void print_menu(FILE *out, node *menu, int indent)
    {
        while (menu != NULL) {
    
            /* Print indent first */
            fprintf(out, "%*s", indent, "");
    
            /* Current menu entry */
            print_path(out, menu);
            fprintf(out, " %s\n", menu->name);
    
            /* Submenu? */
            if (menu->child)
                print_menu(out, menu->child, 3 + indent);
    
            menu = menu->next;
        }
    }
    

    如果您说 node *all; 包含您的菜单树,并且您想将其打印到标准输出,只需调用 print_menu(stdout, all, 0);

    请注意,我喜欢明确指定用于输出的文件句柄,而不是仅仅假设它总是stdout。 (fprintf(stdout, ..FOOBAR..) 等同于 printf(..FOOBAR..)。)这种方法让我可以在打印到文件时使用完全相同的功能,你看。

    通过%*s 打印缩进并不神奇。 s 转换的宽度字段中的* 仅表示printf() 将在要打印的实际字符串之前从int 参数中获取宽度。因此,printf("%*s", n, "") 将打印n 空格。它通常被称为“技巧”,但实际上,它只是有据可查的printf() 行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2016-06-07
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多