'ncurses' 函数 'wgetstr' 正在修改我的变量
`ncurses` function `wgetstr` is modifying my variables
>SOLUTION 显然,wgetstr
函数不会创建新的缓冲区。如果第二个参数被称为 data
并且大小n
并且您输入的字符超过 n
个字符,它将访问并覆盖内存中不属于data
的部分,例如内存中存储cursorY
的位置。为了使一切正常,我用char data[] = " ";
(八个空格)声明了data
并写了wgetnstr(inputWin, data, 8);
.
--------------------------------------------------------------------------------------------------------------
似乎wgetstr
ncurses
函数实际上正在更改我的变量的值。在一个名为 playGame
的函数中,我有一个名为 cursorY
(类型 int
)的变量,每当我按下键盘上的向上或向下箭头时,它就会进行调整(这工作正常)。
请看一下这个代码(inputWin
是WINDOW*
类型):
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 fault
,gdb
说putData
的第一个参数是-1,所以cursorY
必须是0(putData
的前两个参数用于使用SheetCells[row][column]
访问二维数组,其中row
和column
分别是 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
的东西来确保您不会离开缓冲区的末端并造成损坏。
- 如何从子成员函数修改父公共成员变量
- 修改程序的入口点时未调用全局变量的构造函数
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 如何使用gmock模拟修改C++类中私有变量的成员函数
- 有了memory_order_relaxed,原子变量的总修改顺序如何在典型体系结构上得到保证
- 我们如何修改常量变量的值
- 是否可以禁止在for循环体内部修改循环变量
- 使用 QtConcurrent::run() 修改成员变量?
- 在 C++17 中修改 constexpr 函数中的全局变量
- 是否可以在不修改父类的情况下将成员变量初始化推迟到继承的类?
- 如何修改用户指定的变量?
- 打印/修改类对象的特定成员变量,其类定义列表 (STL) 包含的元素类型
- 在击中断点并继续执行VS时,如何在运行时自动修改变量的值
- C 如何使DLL从主线程修改变量
- 使用gcc插件修改变量声明的顺序
- 从子 DLL 访问/修改变量
- QThread:从不同线程修改变量的安全方法
- C++继承子类可修改变量
- 由于在序列点之间修改变量两次而导致的 UB 是否会转移到"inner"范围?
- assert()修改变量时发出警告