Ncurses - 当函数调用中存在多个参数时,为什么不使用 mvprintw() 打印字符串不起作用?
Ncurses - why doesn't printing a string using mvprintw() when multiple arguments in function call are present not work?
我刚开始使用 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
之间跳跃。但是出于某种原因,第二个参数似乎是 "broken"。我什至从数组中删除了检索并使用了硬编码参数值,但仍然没有变化。
进一步调查使我重写了这部分代码,如下所示:
if(data->validity_check != NULL) {
mvprintw(11, 0,
"Validity: %d",
data->validity_check->timestamp);
printw(" [%s]\n", validity[data->validity_check->valid]);
}
它没有任何问题,我得到了想要的结果。但是我不知道我在这里做错了什么。我已经多次查看 documentation 但我可能遗漏了一些东西,因为我找不到任何可以解释这种行为的东西。
你写:
validity_check
is just another struct
that contains a timestamp
(as long integer) and a valid
flag which can be either 0
or 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 中是这样。
我刚开始使用 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
之间跳跃。但是出于某种原因,第二个参数似乎是 "broken"。我什至从数组中删除了检索并使用了硬编码参数值,但仍然没有变化。
进一步调查使我重写了这部分代码,如下所示:
if(data->validity_check != NULL) {
mvprintw(11, 0,
"Validity: %d",
data->validity_check->timestamp);
printw(" [%s]\n", validity[data->validity_check->valid]);
}
它没有任何问题,我得到了想要的结果。但是我不知道我在这里做错了什么。我已经多次查看 documentation 但我可能遗漏了一些东西,因为我找不到任何可以解释这种行为的东西。
你写:
validity_check
is just anotherstruct
that contains atimestamp
(as long integer) and avalid
flag which can be either0
or1
.
如果 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 中是这样。