如何在格式化字符串上使用strlen()?

时间:2012-05-10 12:02:59

标签: c string ncurses strlen formatted

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

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

2 个答案:

答案 0 :(得分:8)

在C99或C11中,您可以使用如下所示的行:

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

来自manual of snprintf(强调我的):

  

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

由于我们将snprintf 0作为大小,因此输出始终被截断,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 */

答案 1 :(得分:0)

您无法事先知道字符串的长度:

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

全部使用相同的格式字符串。

唯一确定的方法是将sprintf相关文字放入缓冲区,strlen(buffer)结果并printf("%s", buffer);将结果显示在屏幕上。

此解决方案避免了双重格式化,但代价是分配足够长的缓冲区。