【发布时间】:2023-07-07 02:21:01
【问题描述】:
我正在尝试学习如何使用 curses 来处理我即将完成的任务的输入。 我得到了一个名为 test-curses.c 的 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 ./测试员
一切都很好,花花公子。但是,当我修改代码以在草图板中移动简单的线条图以响应箭头键时,我遇到了重大错误。 这是我修改后的程序。
#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)
我不明白这告诉我什么,以及文件之间的什么差异导致了这种混乱。请帮忙。
我应该告诉你一些关于以下发送到画板的命令 drawSegment x y x1 y1 在画板窗口中从 (x,y) -> (x1, y1) 绘制一条线 eraseSegment x y x1 y1 擦除该行。
【问题讨论】:
-
听起来你想在 gdb 中运行你的测试程序。这样,当您获得核心转储时,您可以 1) 获得回溯,以及 2) 可能在崩溃时确定相关变量的值。
-
我用 gdb 运行它,它给了我以下附加行 Program received signal SIGABRT, Aborted。 0x00007ffff7609425 在 ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 ../nptl/sysdeps/unix/sysv/linux/raise.c 的 __GI_raise (sig=
) 中:没有这样的文件或目录。 (gdb) -
当 GDB 捕获崩溃时,您可以使用
bt(回溯)命令查看调用链。使用up命令转到您的功能。然后您可以检查变量以查看可能出现的问题。请阅读GDB documentation。