printf 带有空值的缓冲区
是否有一些奇特的 printf 语法可以在打印字符串时忽略空值?
示例用例:打印包含一堆以空结尾的字符串的网络数据包。
我的测试代码来说明问题:
#include <cstdio>
#include <cstring>
void main()
{
char buffer[32];
const char h[] = "hello";
const char w[] = "world";
const int size = sizeof(w) + sizeof(h);
memcpy(buffer, h, sizeof(h));
memcpy(buffer + sizeof(h), w, sizeof(w));
//try printing stuff with printf
printf("prints only 'hello' [%s]\n",buffer);
printf("this prints '<bunch of spaces> hello' [%*s]\n",size,buffer);
printf("and this prints 'hello' [%.*s]\n",size,buffer);
//hack fixup code
for(int i = 0; i < size; ++i)
{
if(buffer[i] == 0)
buffer[i] = ' ';
}
printf("this prints 'hello world ' [%.*s]\n",size,buffer);
}
Is there some fancy printf syntax to ignore nulls when printing a string?
Example use case: printing a network packet that contains a bunch of null terminated strings.
My test code to illustrate the issue:
#include <cstdio>
#include <cstring>
void main()
{
char buffer[32];
const char h[] = "hello";
const char w[] = "world";
const int size = sizeof(w) + sizeof(h);
memcpy(buffer, h, sizeof(h));
memcpy(buffer + sizeof(h), w, sizeof(w));
//try printing stuff with printf
printf("prints only 'hello' [%s]\n",buffer);
printf("this prints '<bunch of spaces> hello' [%*s]\n",size,buffer);
printf("and this prints 'hello' [%.*s]\n",size,buffer);
//hack fixup code
for(int i = 0; i < size; ++i)
{
if(buffer[i] == 0)
buffer[i] = ' ';
}
printf("this prints 'hello world ' [%.*s]\n",size,buffer);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
printf
假定字符串是c 风格的(即以空字符结尾)。您需要执行以下操作之一:1) 使用 ostream 的
write
方法(C++ 风格)2) 使用
write
命令(来自unistd.h< /code>,C 风格)
3)迭代每个字符并打印。
当我调试数据包时,我通常会使用
%02hhx
格式打印出每个字符,以确保我看到确切的代码(没有任何关于将空字符打印到屏幕的怪癖)printf
assumes strings are c-style (i.e. ending in null characters). You need to do one of the following:1) use the
write
method of ostream (C++ style)2) use the
write
command (fromunistd.h
, C style)3) iterate through each character and print.
When I am debugging packets, oftentimes I will print out each character using the
%02hhx
format to be sure I see the exact code (without any quirks about printing null characters to the screen)没有办法告诉
printf
您要打印的字符串的长度。您需要单独打印每个字符:您可以将缓冲区包装在
字符串
中并打印它(如果您不介意重复),因为NULL
不会分隔string
:但更好的是,
您可以使用
std::ostream
的write
,因为您正在使用毕竟 C++:如果你实际上使用 C(为什么你要标记它是 C++ 吗?)你可以这样做:
There isn't a way to tell
printf
the length of the string you want to print. You'll need to print each character individually:You could wrap the buffer in a
string
and print that (if you don't mind the duplication), sinceNULL
s do not delimitstring
s:But better yet
you could use
write
ofstd::ostream
, because you are using C++ after all:If you are actually using C (why'd you tag it C++?) you can do this:
没有想到什么,所以为什么不使用 fwrite() 来代替。假设您知道缓冲区内容的格式,则此操作有效。
如果需要进一步格式化输出,可以在调用 fwrite() 之前和之后使用 printf()。
我没有回应对典型 C++ iostream 的引用,因为我的印象是您更喜欢标准 C 中的某些内容。
There is nothing that comes to mind, so why not use fwrite() instead. This works assuming you know the format of the contents of your buffer.
If you require further formatted output you can use printf() before and after the call to fwrite().
I am not responding with references to typical C++ iostreams because I got the impression you preferred something in standard C.
首先,您的
memcpy
操作每次复制六个字节,因为"hello"
和"world"
都是char[6]< /code>,结果为
h|e|l|l|o|\0|w|o|r|l|d|\0
。这就是为什么您不使用memcpy
复制字符串,而是使用巧妙命名的strcpy
复制字符串。接下来,“如何打印网络数据包”?我有一个实用函数
hexdump
,它以十六行打印任意内存,也许您会发现它很有用:用法:
hexdump(stdout, (const unsigned char*)buffer, 32, " ==>“);
First off, your
memcpy
operations copy six bytes each, since both"hello"
and"world"
arechar[6]
, and the result ish|e|l|l|o|\0|w|o|r|l|d|\0
. That's why you don't copy strings withmemcpy
, but rather with the cleverly namedstrcpy
.Next, "how would you print network packets"? I have a utility function
hexdump
that prints arbitrary memory in lines of sixteen, maybe you'll find it useful:Usage:
hexdump(stdout, (const unsigned char*)buffer, 32, "==> ");
您想忽略空值,还是以某种可见的形式打印它们?
假设是后者,并借用 @Seth 的代码:
替换
cout << ...
如果您使用的是 C 而不是 C++。Do you want to ignore nulls, or print them in some visible form?
Assuming the latter, and borrowing @Seth's code:
Replace
cout << ...
if you're using C rather than C++.