2

我想为mvwprint/mvwchgat ncurses函数编写一个包装函数,该函数在指定窗口中打印消息,然后更改其属性。

但是,mvwchgat需要知道它应该改变多少个字符——而且我不知道如何告诉mvwchgat格式化字符串有多长,例如,因为strlen() on,"abc%d"显然返回 5,因为strlen不知道什么%d代表 ...

4

2 回答 2

9

在 C99 或 C11 中,您可以使用这样的行:

length = snprintf(NULL, 0, format_string, args);

从(强调我的)手​​册中:snprintf

函数 snprintf() 和 vsnprintf() 写入的字节数不超过 size 字节(包括终止的空字节 ('\0'))。如果输出由于此限制而被截断,则返回值是字符数(不包括终止的空字节),如果有足够的可用空间,它将被写入最终字符串。因此,大小或更大的返回值意味着输出被截断。

由于我们给出snprintf0 作为大小,所以输出总是被截断,输出是已经写入snprintf的字符数,这基本上是字符串的长度。

在 C89 中,您没有snprintf. 一种解决方法是创建一个临时文件,或者如果您在 *nix 中打开/dev/null并编写如下内容:

FILE *throw_away = fopen("/dev/null", "w"); /* On windows should be "NUL" but I haven't tested */
if (throw_away)
{
    fprintf(throw_away, "<format goes here>%n", <args go here>, &length);
    fclose(throw_away);
} /* else, try opening a temporary file */
于 2012-05-10T12:06:07.697 回答
-1

您无法提前知道您的字符串有多长:

printf("abc%d", 0); //4 chars
printf("abc%d", 111111111);//12 chars

都具有相同的格式字符串。

唯一确定的方法是将sprintf有问题的文本放入缓冲区,strlen(buffer)将结果和printf("%s", buffer);结果进行筛选。

该解决方案以分配足够长的缓冲区为代价避免了双重格式化。

于 2012-05-10T12:18:15.617 回答