如何在printf菜单(“选项1 \ n选项2 \ n选项3”)上移动printf指示器(“ ==>”)?

时间:2019-08-05 15:46:39

标签: c windows conio

我正在使用箭头键作为输入,以在[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/app/current/artisan queue:listen --tries=3 autostart=true autorestart=true user=webapp numprocs=5 redirect_stderr=true stdout_logfile=/var/app/current/storage/worker.log 菜单上上下移动printf箭头(“ ==>”)。

我正在使用一个函数来计算箭头的位置,并使用printf大小写和switch来放置箭头的位置,但是它也会在新行中打印菜单。

printf("\n==>")

当它在第二个和第三个箭头上打印菜单时,菜单也会在新行上打印。

不是看起来像

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

void menu(void);
int arrowPos(void);

int main(void)
{
    int aDet, aDet2;
    int aCnt;

    for(;;)
    {
        aDet = getch();
        aDet2 = 0;
        if(aDet == 0xE0)
        {
            aDet2 = getch();
            if(aDet2 == 80) arrowPos();
        }
    }
    return 0;
}

int arrowPos(void)
{
    int aCnt;

LOOP:
    aCnt++;

    switch(aCnt)
    {
    case 1:
        system("cls");
        printf("==>");
        //  menu();
        break;
    case 2:
        system("cls");
        printf("\n==>");
        break;
    case 3:
        system("cls");
        printf("\n\n==>");
        //  menu();
        break;
    case 4:
        aCnt = 0;
        goto LOOP;
        break;
    }

    menu();
    //printf("%d",aCnt);
}

void menu(void)
{
    printf("Option 1\n");
    printf("Option 2\n");
    printf("Option 3");
}

看起来像

 Option1
 Option2
 ==>Option3

2 个答案:

答案 0 :(得分:1)

我认为最干净的方法是包含选项的数组。 遍历数组时,可以在正确的索引处打印箭头。

#define OPTION_CNT 3
const char *option_texts[OPTION_CNT] = {
    "Option 1",
    "Option 2",
    "Option 3"
};
const char * arrow_text = "==>";

void menu(size_t arrowIndex){
    for(size_t i = 0; i < OPTION_CNT; ++i){
        if(i == arrowIndex){
            printf("%s ", arrow_text);
        }
        printf("%s\n", option_texts[i]);
    }
}

如果您不能停止以OO方式思考,还可以通过创建一个结构来扩展此结构,该结构不仅包含要显示的文本,而且还包含选择该选项时调用的方法。

#define OPTION_CNT 3
typedef void OptionHandler();
struct Option {
    OptionHandler *handler;
    const char *text;
} options[OPTION_CNT] = {
    {doSomething1, "Option 1"},
    {doSomething2, "Option 2"},
    {doSomething3, "Option 3"}
}

然后您可以替换行

printf("%s\n", option_texts[i]);

printf("%s\n", options[i].text);

选择该选项后,您只需

options[aCnt].handler();

因此,所有选项定义都集中在一个位置,您可以摆脱这些switch语句。

答案 1 :(得分:0)

建议不要将箭头和选项文本分别打印,而应该将它们组合在一起。

示例:

/* ... */
if(aCnt > 3)
{
   aCnt = 1;

   menu(aCnt)
}
/* ... */

static void menu(int aCnt)
{
   const char *arrow = "==>";
   const char *empty = "";

   /* this is not portable and should be replaced */
   system("cls");
   printf("%sOption 1\n", (aCnt == 1)?arrow:empty);
   printf("%sOption 2\n", (aCnt == 2)?arrow:empty);
   printf("%sOption 3", (aCnt == 3)?arrow:empty);

}