链表菜单以特定行数进行显示,思路是否正确?

#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "malloc.h"
#include <windows.h>
typedef struct Node
{
    struct Node *father;
    struct Node *brother_up;
    struct Node *brother_dw;
    struct Node *son;
    uint8_t *str;  
    uint8_t val_only4father;
}Node_T;
Node_T *head,*temp;

Node_T *creat_father(uint8_t *str)
{
    Node_T *temp=NULL;
    temp=(Node_T *)malloc(sizeof(Node_T));
    if(temp==NULL)
    {
        return NULL;
    }
    temp->father=temp;
    temp->brother_up=NULL;
    temp->brother_dw=NULL;
    temp->son=NULL;
    temp->str=str;
    temp->val_only4father=0x01;
    printf("creat_father succeed\r\n");
    printf("%s\t\t%x\r\n",temp->str,temp);
    return temp;
}
Node_T *creat_brother(Node_T *brother,uint8_t *str)
{
    Node_T *temp=NULL;
    Node_T *temp_1=brother;
    temp=(Node_T *)malloc(sizeof(Node_T));
    if(temp==NULL)
    {
        return NULL;
    }
    temp->father=temp_1->father;
    while (temp_1->brother_dw!=NULL)
    {
        temp_1=temp_1->brother_dw;
    }
    temp_1->brother_dw=temp;
    temp->brother_up=temp_1;
    temp->brother_dw=NULL;
    temp->son=NULL;
    temp->str=str;
    printf("creat_brother succeed\r\n");
    printf("%s\t\t%x\r\n",temp->str,temp);
    return temp;
}
Node_T *creat_son(Node_T *father,uint8_t *str)
{
    Node_T *temp=NULL;
    Node_T *temp_1=father;
    temp=(Node_T *)malloc(sizeof(Node_T));
    if(temp==NULL)
    {
        return NULL;
    }
    temp->father=temp_1;
    temp_1->son=temp;
    temp->son=NULL;
    temp->brother_dw=NULL;
    temp->brother_up=NULL;
    temp->str=str;
    printf("creat_son succeed\r\n");
    printf("%s\t\t%x\r\n",temp->str,temp);
    return temp;
}
#define PO(X) if(X!=NULL){printf("%s\t",X->str);}
Node_T *dirnow;
void showlist(Node_T *Nodex)
{
    Node_T* Node;
    Node_T* nextson;
    Node=Nodex;
    if(Node!=NULL)
    {
        printf("printf enter\r\n");
        while (Node->son!=NULL)
        {
            
            printf("%s\r\n",Node->str);
            printf("\t%x\r\n",Node);
            Node=Node->son;
        }
        printf("--------------\r\n");
        // printf("%s\r\n",Node->str);
        // if(Node->brother_dw!=NULL)
        //     printf("%s\r\n",Node->brother_dw->str);
        // if(Node->brother_up!=NULL)
        //     printf("%s\r\n",Node->brother_up->str);
        // if(Node->father!=NULL)            
        // printf("%s\r\n",Node->father->str);
        // PO(Node);
        // PO(Node->brother_dw);
        // PO(Node->brother_up);
        // PO(Node->father);
        // PO(Node->father->brother_dw);
        // printf("\r\n");
        printf("--------------\r\n");
        while (Node->father!=NULL)
        {
            printf("%s\r\n",Node->str);
            printf("\t%x\r\n",Node);

            if(Node->val_only4father==0x01)
            {
                break;
            }
            Node=Node->father;
        }
        printf("++++++++++++++++++++++++++\r\n");
        // PO(Node);
        // PO(Node->son);
        // PO(Node->son->brother_dw);
        // PO(Node->son->brother_up);
        Node=Node->son;
        dirnow=Node;
        while(Node!=NULL)
        {
            PO(Node);
            printf("\t");
            PO(Node->son);
            Node=Node->brother_dw;
            printf("\r\n");
        }
        printf("\r\nprintf done");
    }
    else
    {
        printf("fail\r\n");
    }
}

void show_list_menu(Node_T *now)
{
    Node_T *temp=now;
    Node_T *display_dir=now;

    while (temp->brother_up!=NULL)
    {
        temp=temp->brother_up;
    }
    
    while(temp!=NULL)
    {

        if(temp->str==dirnow->str)printf("->");
        PO(temp);
        printf("\r\n");
        temp=temp->brother_dw;
    }

}
void getkey(void)
{
    uint8_t keyval=getch();
    switch (keyval)
    {
    case 'A':
    case 'a':
            if(dirnow->father!=NULL)dirnow=dirnow->father;
        break;
    case 'd':
    case 'D':
            if(dirnow->son!=NULL)dirnow=dirnow->son;
        break;
    case 'W':
    case 'w':
            if(dirnow->brother_up!=NULL)
            {
                dirnow=dirnow->brother_up;

                
            }
        break;    
    case 's':
    case 'S':
            if(dirnow->brother_dw!=NULL)
            {
                dirnow=dirnow->brother_dw;

                
            }
        break; 
    default:
        break;
    }
}

void showmenu(Node_T* now)
{
    Node_T* show;
    show = now;
 

    while (show->brother_up != NULL)//先依次往最上面找大哥
        show = show->brother_up;
    
    while (show!= NULL)//从大哥开始往下显示所有小弟
    {
        if (now->str == show->str)//标记现在指针指向的位置
            printf("->");
 
        printf("%s\r\n",show->str);
        show = show->brother_dw;
    }
}
int main(void)
{
    Node_T *head,*temp,*tx;
    head=creat_father("fat");
    temp=creat_son(head,"son-1");
    tx=creat_brother(temp,"son-2");
    creat_brother(temp,"son-3");
    creat_brother(temp,"son-4");
    creat_brother(temp,"son-5");
    dirnow=head;
    creat_son(tx,"son-2-1");
    creat_brother(tx,"son-6");
    tx=creat_son(temp,"son-1-1");
    creat_son(tx,"son-1-1-1");
    creat_brother(tx,"son-1-2");
    tx=creat_son(tx,"son-1-1-1-1");
    creat_brother(tx,"son-1-1-1-2");
    creat_brother(tx,"son-1-1-1-3");
    show_list_menu(dirnow);
    system("pause");
    showmenu(dirnow);
    while (1)
    {
        getkey();
        system("cls");
        // showmenu(dirnow);
        show_list_menu(dirnow);
    }
    

}

image.png
上图是在终端上呈现的效果


目前已实现 :

  1. 以链表的方式建立菜单
  2. 上下级菜单切换正常
    问题描述:
    由于最终菜单是以oled/LCD[128x64]的屏幕进行显示,同屏下只能显示4行或其它固定行。
    所以就要求进行翻页。
    目前的思路是 通过获取当前级菜单的总项数[get_node_num],如上图示为6项,然后假定屏幕最大显示4项[set_dis_row],再设定一个当前箭头所在的项数[cur_node_row],此变量在按键中进行对应的加减操作,初始为0,求得[page]=cur_node_row/set_dis_row。在显示前对节点进行移位操作node=node->bro_dw.
    不知道上面的思路是否有问题?通过编程实现,所得的现象与预期的不一样。
阅读 1.2k
1 个回答
void display_by_row(Node_T *now)
{
    Node_T *temp = now;
    Node_T *display_dir = now;

    // while (temp->brother_up != NULL)
    // {
    //     temp = temp->brother_up;
    // }
    for(uint8_t i=0;i<3;i++)
    {
        if (temp != NULL)
        {

            if (temp->str == dirnow->str)
                printf("->");
            PO(temp);
            printf("\r\n");
            temp = temp->brother_dw;
        }

    }
    
}

将原void show_list_menu(Node_T *now)-->改成上述方式。
原打印方法是:找到最先的兄弟结点,再通过while进行循环打印。
现在的打印方式:以当前的结点做为起点,(此起点一直在变动,在按键发生变化时)。再通过for循环(指定循环次数,4 表示 4行显示)。
最终效果如下:
image.png
初始显示
image.png
显示
image.png
显示

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题