Question

Im learning curses library by tutorials and Ive replaced a switch statement by multiple if (the switch part is still on commentary) on a curses tutorial because I better understand with if statement My problem is that now each time I press a key, the previous entered key is used before the new one, whats wrong ?

int             main(int argc, char *argv[])
{WINDOW *my_win;
  int startx, starty, width, height;
  int ch;

  initscr();/* Start curses mode */
  cbreak();/* Line buffering disabled, Pass on                                                                   
            * everty thing to me */
  keypad(stdscr, TRUE);/* I need that nifty F1 */

  height = 3;
  width = 12;
  starty = (LINES - height) / 2;/* Calculating for a center placement */
  startx = (COLS - width) / 2;/* of the window*/
  printw("Press F1 to exit");
  refresh();
  my_win = create_newwin(height, width, starty, startx);
  /*                                                                                                             
  while((ch = getch()) != KEY_F(1))                                                                              
    {switch(ch)                                                                                                  
        {case KEY_LEFT:                                                                                          
            destroy_win(my_win);                                                                                 
            my_win = create_newwin(height, width, starty,--startx);                                              
            break;                                                                                               
        case KEY_RIGHT:                                                                                          
          destroy_win(my_win);                                                                                   
          my_win = create_newwin(height, width, starty,++startx);                                                
          break;                                                                                                 
        case KEY_UP:                                                                                             
          destroy_win(my_win);                                                                                   
          my_win = create_newwin(height, width, --starty,startx);                                                
          break;                                                                                                 
        case KEY_DOWN:                                                                                           
          destroy_win(my_win);                                                                                   
          my_win = create_newwin(height, width, ++starty,startx);                                                
          break;                                                                                                 
        }                                                                                                        
    }
  */
  while(42)
    {
      ch = getch();
    if(ch == KEY_LEFT)
      {
        destroy_win(my_win);
        my_win = create_newwin(height, width, starty,startx--);
      }
    else if(ch == KEY_RIGHT)
      {
        destroy_win(my_win);
        my_win = create_newwin(height, width, starty,startx++);
      }
    else if(ch == KEY_UP)
      {
        destroy_win(my_win);
        my_win = create_newwin(height, width, starty--,startx);
      }
    else if(ch == KEY_DOWN)
      {
        destroy_win(my_win);
        my_win = create_newwin(height, width, starty++, startx);
      }
    else
      {
        endwin();
        exit(0);
      }

  }
  endwin();/* End curses mode  */
  return 0;
}

WINDOW *create_newwin(int height, int width, int starty, int startx)
{WINDOW *local_win;

  local_win = newwin(height, width, starty, startx);
  box(local_win, 0 , 0);/* 0, 0 gives default characters                                                         
                         * for the vertical and horizontal                                                       
                         * lines*/
  wrefresh(local_win);/* Show that box */

  return local_win;
}

void destroy_win(WINDOW *local_win)
{
  /* box(local_win, ' ', ' '); : This won't produce the desired                                                  
   * result of erasing the window. It will leave it's four corners                                               
   * and so an ugly remnant of window.                                                                           
   */
  wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
  /* The parameters taken are                                                                                    
   * 1. win: the window on which to operate                                                                      
   * 2. ls: character to be used for the left side of the window                                                 
   * 3. rs: character to be used for the right side of the window                                                
   * 4. ts: character to be used for the top side of the window                                                  
   * 5. bs: character to be used for the bottom side of the window                                               
   * 6. tl: character to be used for the top left corner of the window                                           
   * 7. tr: character to be used for the top right corner of the window                                          
   * 8. bl: character to be used for the bottom left corner of the window                                        
   * 9. br: character to be used for the bottom right corner of the window                                       
   */
  wrefresh(local_win);
  delwin(local_win);
}
Was it helpful?

Solution

The switch to if conversion wasn't the only change you've made. You introduced mistakes like the following, where:

my_win = create_newwin(height, width, starty, --startx);

became:

my_win = create_newwin(height, width, starty, startx--);

That is, prefix decrement became postfix, changing the value that is passed to create_newwin(); prefix decrement evaluates to the value after the decrement, while postfix to the value before. That means the old position is used to draw the window, giving the effect as if the bug has something to do with the input key while the problem has actually nothing to do with it.

You did the same with all the other prefix increments in the original code. You should change them all from postfix to prefix, and the code will behave the same.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top