我刚刚开始使用
ncurses
。数组 validity
定义为
static const char* validity[] = {
"invalid",
"valid"
};
允许我在必要时将
0
映射到 invalid
并将 1
映射到 valid
,以便在我的应用程序中生成更具可读性的输出。
我的代码中还有以下几行:
if(data->pos != NULL) {
mvprintw(4, 0,
"Position: X %5d Y %5d Z %5d \n",
data->pos->x, data->pos->y, data->pos->z);
// ...
}
这允许我输出存储在
struct data
内的 3D 坐标,该坐标每秒更新多次并填充新坐标。它可以正常工作,没有任何问题。
接下来我要做的是使用
mvprintw(...)
输出单个字符串参数:
if(data->detected != NULL) {
mvprintw(5, 0,
"Detected: %s\n",
booleans[data->detected]);
}
其中
booleans
与 validity
数组非常相似,但内部有 true
和 false
字符串,用于将布尔值映射到字符串。这也有效!
但是下面的代码输出了一个奇怪的结果:
if(data->validity_check != NULL) {
mvprintw(11, 0,
"Validity: %d [%s]\n",
data->validity_check->timestamp,
validity[data->validity_check->valid]);
}
validity_check
只是另一个 struct
,其中包含 timestamp
(作为长整数)和 valid
标志,可以是 0
或 1
。
输出应该类似于
Validity: 123456789 [invalid]
但我得到了
Validity: 123456789 [(null)]
我对此感到非常惊讶,并使用
printf()
进行输出,以查看 valid
是否实际上包含有效数据(这就是 C 数组的问题 - 不检查越界)。结果:确实如此。正如预期的那样,这些值在 0
和 1
之间跳跃。然而,出于某种原因,第二个论点似乎是“错误的”。我什至从数组中删除了检索并使用了硬编码的参数值,但仍然没有变化。
进一步的调查使我重写了这部分代码,如下所示:
if(data->validity_check != NULL) {
mvprintw(11, 0,
"Validity: %d",
data->validity_check->timestamp);
printw(" [%s]\n", validity[data->validity_check->valid]);
}
它运行没有任何问题,并且得到了我想要的结果。但是我不知道我在这里做错了什么。我已经多次查看文档,但我可能遗漏了一些东西,因为我找不到任何可以解释这种行为的东西。
你写:
只是另一个validity_check
,其中包含struct
(作为长整数)和timestamp
标志,可以是valid
或0
。1
如果
timestamp
是 long int
,则应使用 %ld
格式,而不仅仅是 %d
:
if (data->validity_check != NULL) {
mvprintw(11, 0,
"Validity: %ld [%s]\n",
data->validity_check->timestamp,
validity[data->validity_check->valid]);
}
printf
函数系列是可变函数,格式字符串必须准确地告诉它们要使用哪种类型。 (这与普通函数不同,普通函数的参数类型是已知的,并且类型会根据需要缩小或提升。)
这是一种常见的错误类型,但启用警告应该会告诉您此类格式不匹配的情况,至少在 GCC 和 Clang 中是这样。