'ncurses' 函数 'wgetstr' 正在修改我的变量

`ncurses` function `wgetstr` is modifying my variables

本文关键字:修改 变量 我的 wgetstr ncurses 函数      更新时间:2023-10-16

>SOLUTION 显然,wgetstr函数不会创建新的缓冲区。如果第二个参数被称为 data 并且大小n并且您输入的字符超过 n 个字符,它将访问并覆盖内存中不属于data的部分,例如内存中存储cursorY的位置。为了使一切正常,我用char data[] = " ";(八个空格)声明了data并写了wgetnstr(inputWin, data, 8);.

--------------------------------------------------------------------------------------------------------------

似乎wgetstr ncurses函数实际上正在更改我的变量的值。在一个名为 playGame 的函数中,我有一个名为 cursorY(类型 int)的变量,每当我按下键盘上的向上或向下箭头时,它就会进行调整(这工作正常)。

请看一下这个代码(inputWinWINDOW*类型):

mvprintw(0, 0, (to_string(cursorY)).c_str());
refresh();
usleep(500000);
wgetstr(inputWin, data);
mvprintw(0, 0, (to_string(cursorY)).c_str());
refresh();
usleep(500000);

假设我将光标移动到第 6 行,然后按 Enter 键(这会导致执行这段代码)。我可以做两件事:

  • 只需输入 1 个字符。两次refresh调用后,值 6 将显示在屏幕上(位置 (0, 0))。
  • 输入 2 个或更多字符。在这种情况下,在第一次refresh调用之后,我只得到 6,但在第二次调用之后,我神奇地得到 0。

上面代码后面的前两行是

noecho();
_theView -> _theActualSheet -> putData(cursorY-1, cursorX/9 - 1, data);

(不要担心参数:关于它们的数学检查出来)。当我在putData时,我得到了一个Segmentation faultgdbputData的第一个参数是-1,所以cursorY必须是0(putData的前两个参数用于使用SheetCells[row][column]访问二维数组,其中rowcolumn分别是 putData 的第一个和第二个形式参数)。

显然,wgetstr修改了cursorY的价值。后一个变量的名称无关紧要:将其更改为cursorrY或像monkeyBusiness这样奇怪的东西(是的,我已经尝试过了)不起作用。什么样的工作是用上面的代码段替换

mvprintw(0, 0, (to_string(cursorY)).c_str());
refresh();
usleep(500000);
int a = cursorY;
wgetstr(inputWin, data);
cursorY = a;
mvprintw(0, 0, (to_string(cursorY)).c_str());
refresh();
usleep(500000);

在这两种情况下,我都会在屏幕的左上角看到 6。但是,知道字符串的行为很奇怪:当我输入asdf作为我的字符串时,然后向右移动(即,我在键盘上按右键),然后再次输入asdf,我得到as^a

所以基本上,我想知道两件事:

  • 为什么地狱wgetstr改变我的变量?
  • 为什么只有当我输入超过 1 个字符时才会发生?
  • 一般来说,wgetstr似乎有什么问题?在处理输入方面似乎很糟糕。

我可以尝试其他事情(例如手动读取字符,然后将它们连接data),但wgetstr似乎非常适合我想做的事情,我没有理由在这里切换。

任何帮助都非常感谢。(请记住:我特别想知道为什么cursorY的值会发生变化。如果您建议不使用wgetstr并且有一个很好的选择,请告诉我,但我最感兴趣的是知道为什么cursorY被更改。

编辑 变量 data 的类型为 char[],声明如下:char data[] = "" .我不"清除"这个变量(即删除所有"字母"),但我认为这没有任何区别,因为我认为wgetstr只是覆盖了整个变量(或者我在这里大错特错?

为数据提供的缓冲区 data 定义为单个字符长(只有 null 终止符)。这意味着,如果您输入一个或多个字符的任何输入,您将在数据提供的空间之外写入,从而覆盖其他内容。看起来光标Y是被击中的幸运变量。

您需要确保数据至少足够大以处理所有输入。最好是切换到一些输入函数(如wgetnstr),该函数将允许您传递缓冲区的大小,否则总是可以通过键入足够的字符来使应用程序崩溃。

wgetstr期望将收到的字符写入预分配的缓冲区,该缓冲区至少应与预期的输入字符串一样长。它不会为您分配新的缓冲区!

您所做的是为其提供单字节缓冲区,并向其中写入多个字节。这将踩踏您在函数中定义的其他变量 data ,例如 cursorY无论它叫什么。对变量的任何更改都会反过来更改读入的字符串:

int a = cursorY;
wgetstr(inputWin, data);
cursorY = a;

会将一个 int 值写入您的字符串,这就是为什么它显然被损坏的原因。

您实际上应该做的是使data实际上足够长,以满足预期的输入,理想情况下使用类似wgetnstr的东西来确保您不会离开缓冲区的末端并造成损坏。