C++ 无法使用ncurses确定终端大小

C++ 无法使用ncurses确定终端大小,c++,macos,ncurses,C++,Macos,Ncurses,我正在尝试处理调整大小信号(SIGWINCH) void服务器::resizeSignalHandler(int a) { 信号(信号绞车、信号灯); endwin(); initscr(); 刷新(); 清除(); int x,y; getmaxyx(stdscr,y,x); wmove(屏幕上方,0,0); wmove(向下屏幕,y/2,0); 尺寸(屏幕上方,y/2,x); 尺寸(向下屏幕,y/2,x); wclear(屏幕上); wclear(屏幕下); waddstr(屏幕上方,“测试

我正在尝试处理调整大小信号(SIGWINCH)

void服务器::resizeSignalHandler(int a)
{
信号(信号绞车、信号灯);
endwin();
initscr();
刷新();
清除();
int x,y;
getmaxyx(stdscr,y,x);
wmove(屏幕上方,0,0);
wmove(向下屏幕,y/2,0);
尺寸(屏幕上方,y/2,x);
尺寸(向下屏幕,y/2,x);
wclear(屏幕上);
wclear(屏幕下);
waddstr(屏幕上方,“测试1”);
waddstr(屏幕下方,“测试2”);
刷新(屏幕上);
wrefresh(向下屏幕);
刷新();
信号(SIGWINCH,服务器::resizeSignalHandler);
}
服务器::服务器()
{
//ncurses屏幕初始化
initscr();
如果(!屏幕上方){
屏幕上方=newwin(0,0,1,1);
}
如果(!向下屏幕){
向下屏幕=newwin(0,0,1,1);
}
//用户调整终端尺寸时的屏幕调整
信号(SIGWINCH,服务器::resizeSignalHandler);
//配置屏幕
服务器::resizeSignalHandler(0);
waddstr(服务器::屏幕上的“lalfasdfsafdas”);
waddstr(屏幕下方,“至尊!”);
wrefresh(服务器::屏幕上方);
wrefresh(向下屏幕);
}
当我调试这段代码时,在resizeSignalHandler变量x中,y总是相同的(大小没有改变)。我还尝试用ioctl确定大小,但没有任何改变

我发现在我之前很多人都有这个问题 有时,他们会解决这个问题(更改/etc/profile;O(原文如此!)),但有时不会。
是否有mac os x终端的替代方案,也许ncurses专用于xterm和类似产品

我没有mac电脑,无法测试。但是我假设伪终端bash在更新$行和$列上运行,但是这些更新不会传递给程序分配给的伪终端。这是因为您说绞车信号被捕获,但这些参数没有更新。解决方法是在信号处理程序中执行
“/usr/X11/bin/resize”
/
“/usr/bin/resize”
。可能这会正确地更新$line和$COLUMNS。

我不确定,但我认为您必须调用
ioctl(1,TIOCGWINSZ,struct winsize*)
来获取更新的终端参数。请参见
mantty\u ioctl

,这是因为通过
getmaxyx
获得的值由侦听
SIGWINCH
的信号处理程序自动更新。您需要使用以下内容保存指向旧信号的指针:

old_callback = signal(SIGWINCH, Server::resizeSignalHandler);
然后在
resizeSignalHandler
中调用它:

old_callback(a);
getmaxyx(…)
由于自定义
SIGWINCH
信号处理程序,给出了错误(未更新)的终端大小

您可以使用
ioctl(fileno(stdout)、TIOCGWINSZ、struct winsize*)
获取更新的终端参数。但这不会更新由
getmaxyx(…)
返回的数据

要更新
getmaxyx(…)
数据,您应该调用
resize\u term(size.ws\u row,size.ws\u col)

因此,信号处理程序代码应该如下所示:

void on_terminal_resize(int n) {
    struct winsize size;

    if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
        resize_term(size.ws_row, size.ws_col);
    }
    // Your code goes here...
    signal(SIGWINCH, on_terminal_resize);
}

您可以使OSX术语的行为与xterm相同,因此这不是问题所在。你真的是在终端上测试还是用XCode的假术语测试?它不能用XCode测试。在终端中。问题中显示的示例干扰了ncurses设置的处理程序,并且不安全。没有一个建议的答案是有用的…事实上它是有效的。但当我尝试读取shell变量(通过echo$行)时,它返回不正确的值(如ioctl、getmaxyx等),谢天谢地,/usr/X11/bin/resize直接返回正确的信息——所以我只是从字符串中去除所需的信息。