-1

I'm using arrow keys as inputs to move a printf arrow ("==>") up and down a printf menu.

I'm using a function that counts where the arrow should be and using switch cases and printf("\n==>") to place where the arrow should be, but it prints the menu in a new line as well.

#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");
}

When it prints the menu on the second and third arrow the menu is also printed on a new line.

Instead of looking like

 Option1
 Option2
 ==>Option3

it looks like

 ==>Option1
 Option2
 Option3
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76

2 Answers2

1

I think the cleanest way is an array containing the options. While iterating over the array you can print the arrow at the right index.

#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]);
    }
}

If you can not stop thinking in a OO manner you can also extend this by creating a struct which not only contains the text to be displayed but also the method which gets called when the option is selected.

#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"}
}

then you can replace the line

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

with

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

and when that option gets selected you simply

options[aCnt].handler();

Thus you have all the option-definitions at one place and you can get rid of those switch statements.

Burdui
  • 1,242
  • 2
  • 10
  • 24
0

Instead of trying to print the arrow and the option text separately, I suggest to combine it.

Example:

/* ... */
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);

}
Bodo
  • 9,287
  • 1
  • 13
  • 29