如何正确使用curses /调试简单的c程序

时间:2012-11-14 01:45:13

标签: c ncurses curses

我正在尝试学习如何使用curses来处理即将到来的作业的输入。 我得到了一个名为test-curses.c的程序,其中包含以下代码......

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>

// brief example of using curses.
// man 3 ncurses for introductory man page, and man 3 function name
// for more information on that function.

void setup_curses();
void unset_curses();

int main()
{

 setup_curses();

 move(5, 10);
 printw("Press any key to start.");
 refresh();
 int c = getch();

 nodelay(stdscr, true);
 erase();

 move(5, 10);
 printw("Press arrow keys, 'q' to quit.");
 refresh();

 c = getch();

 while(1)
 {
   if (c != ERR)
    {
  // in asn3, won't need to do any printing to screen.
  // instead, will rotate figure on left or right arrow keys, and
  // initiate thrust when space bar is pressed.
  erase();
  move(5,10);
  printw("Press arrow keys, 'q' to quit.");
  move(6, 10);
  if (c == KEY_DOWN)
    printw("down key pressed");
  else if (c == KEY_LEFT)
    printw("left key pressed");
  else if (c == KEY_RIGHT) 
    printw("right key pressed");
  else if (c == KEY_UP)
    printw("up key pressed");
  else if (c == 'q')
    break;
  refresh();

   }

   c = getch();

}

// must do this or else Terminal will be unusable
// (if there are problems, it's not that big a deal though ... just
// close the Terminal, and open a new one.)
unset_curses();

exit(EXIT_SUCCESS);
}

void setup_curses()
{
  // use return values.  see man pages.  likely just useful for error
  // checking (NULL or non-NULL, at least for init_scr)
  initscr();
  cbreak();
  noecho();
  // needed for cursor keys (even though says keypad)
  keypad(stdscr, true);
}

void unset_curses()
{
  keypad(stdscr, false);
  nodelay(stdscr, false);
  nocbreak();
  echo();
  endwin();
}

我通过在终端中键入以下内容来运行此程序  gcc -std = c99 -Wall -o tester test-curses.c -lcurses  ./tester

一切都很好,花花公子。然而,当我修改代码以在草图板中移动简单的线条图以响应箭头键时,我得到了主要的错误。 这是我修改过的程序。

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

// brief example of using curses.
// man 3 ncurses for introductory man page, and man 3 function name
// for more information on that function.
typedef struct {
  long x, y, x1, y1;
  long deltax, deltay, deltax1, deltay1;
 } line_item;

line_item *line;
FILE * popen(const char*, const char*);
int pclose(FILE*);
void setup_curses();
void unset_curses();
void draw(line_item * line, FILE * executable);
void translate(line_item * line, double trans_x, double trans_y);

int main()
{
  FILE * executable;
  executable = popen("java -jar Sketchpad.jar", "w");
  assert( executable != NULL);

  setup_curses();

  move(5, 10);
  printw("Press any key to start.");
  refresh();
  int c = getch();

  nodelay(stdscr, true);
  erase();

  move(5, 10);
  printw("Press arrow keys, 'q' to quit.");
  refresh();

  c = getch();

  while(1)
  {
    if (c != ERR)
    {
      // in asn3, won't need to do any printing to screen.
      // instead, will rotate figure on left or right arrow keys, and
      // initiate thrust when space bar is pressed.
      erase();
      move(5,10);
      printw("Press arrow keys, 'q' to quit.");
      move(6, 10);
      if (c == KEY_DOWN){
        printw("down key pressed");
        translate(line, 0, -10);
        draw(line, executable);
      }
      else if (c == KEY_LEFT){
        printw("left key pressed");
        translate(line, -10, 0);
        draw(line, executable);
      }
      else if (c == KEY_RIGHT){ 
        printw("right key pressed");
        translate(line, 10, 0); 
        draw(line, executable); 
      }
      else if (c == KEY_UP){
        printw("up key pressed");
        translate(line, 10, 0); 
        draw(line, executable); 
      }
      else if (c == 'q')
        break;
      refresh();

    } 

    c = getch();
    pclose(executable);
  }

  // must do this or else Terminal will be unusable
  // (if there are problems, it's not that big a deal though ... just
  // close the Terminal, and open a new one.)
  unset_curses();

  exit(EXIT_SUCCESS);
}

void draw(line_item * line, FILE * executable)
{
  fprintf(executable, "eraseSegment %ld %ld %ld %ld", line->x, line->y, line->x1, line->y1);
  fprintf(executable, "drawSegment %ld %ld %ld %ld", line->deltax, line->deltay, line->deltax1, line->deltay1);
  fflush(executable);
}
void translate(line_item * line, double trans_x, double trans_y)
{
  line->x = line->deltax;
  line->y = line->deltay;
  line->x1 = line->deltax1;
  line->y1 = line->deltay1;

  line->deltax = line->x + trans_x;
  line->deltax1 = line->x1 + trans_x;
  line->deltay = line->y + trans_y;
  line->deltay1 = line->y1 + trans_y;
}

void setup_curses()
{
  // use return values.  see man pages.  likely just useful for error
  // checking (NULL or non-NULL, at least for init_scr)
  initscr();
  cbreak();
  noecho();
  // needed for cursor keys (even though says keypad)
  keypad(stdscr, true);
}

void unset_curses()
{
  keypad(stdscr, false);
  nodelay(stdscr, false);
  nocbreak();
  echo();
  endwin();
}

当前目录包含这两个程序和Sketchpad.jar。我运行第二个时得到的错误就像这样......

ses.so.5.9
          7f100a23a000-7f100a23b000 r--p 0001f000 08:01 2882225                    /lib/x86_64-linux-gnu/libncurses.so.5.9
          7f100a23b000-7f100a23c000 rw-p 00020000 08:01 2882225                    /lib/x86_64-linux-gnu/libncurses.so.5.9
          7f100a23c000-7f100a25e000 r-xp 00000000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7f100a428000-7f100a42c000 rw-p 00000000 00:00 0 
          7f100a45b000-7f100a45e000 rw-p 00000000 00:00 0 
          7f100a45e000-7f100a45f000 r--p 00022000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7f100a45f000-7f100a461000 rw-p 00023000 08:01 2877975                    /lib/x86_64-linux-gnu/ld-2.15.so
          7ffffa0be000-7ffffa0df000 rw-p 00000000 00:00 0                          [stack]
         7ffffa19e000-7ffffa19f000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
       Aborted (core dumped)

我不明白这告诉我什么,文件之间的差异导致了这个混乱。请帮忙。

我应该告诉你一些关于发送到sketchpad的以下命令 drawSegment x y x1 y1从(x,y) - &gt;中绘制一条线。画板窗口中的(x1,y1) eraseSegment x y x1 y1删除该行。

1 个答案:

答案 0 :(得分:0)

对于初学者来说,你的线指针永远不会指向任何真实的东西。这可能会导致核心转储。

您可以执行的最小编辑修复: -

line_item _line;
line_item *line;

然后在main中,在循环之前执行: -

line = &_line;