如何在c++中在cout/cerr上打印USB字符串描述符
How to print a USB string descriptor on cout/cerr in c++?
我在uint8_t数组中有一个USB字符串描述符。例如:
0000:12 03 34 00 45 00 36 00 31 00 42 00 43 00 30 00 ..4.E.6.1.B.C.0.
0010:30 00 0.
(前两个字节是长度和描述符类型;剩下的字节是uint16_t类型的字符。)
我想在终端上打印这个,尽可能少的麻烦,最好不用和所有其他打印(发生像cout << "Hello, world" << endl;
)乱搞。
我特别想做的是:
cout << "Serial number is: " << some_cast_or_constructor( buf + 2, len - 2 ) << endl;
对于上面的字符串描述符,在终端上获得以下内容:
Serial number is: 4E61BC00
这是可能的吗,还是我必须钻研Unicode的奥秘?
[edit to add:]
Per @PaulMcKenzie,我尝试了这个程序:
#include <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <locale>
int
main( int argc, char **argv )
{
char buf[] = { 34, 00, 45, 00, 36, 00, 31, 00, 42, 00, 43, 00, 30, 00, 30, 00 };
std::wcout << "Hello" << std::wstring( (const wchar_t *)buf, sizeof(buf) ) << std::endl;
return 0;
}
输出:user:/tmp$ g++ foo.cc
user:/tmp$ ./a.out
Hello??????????
user:/tmp$
在你的源代码中,我检测到两个错误:1-在你的USB原始数据(在顶部),值是十六进制,在你的buf[]值是十进制。应该这样写:
char buf[] = { 0x34, 0x00, 0x45, 0x00, 0x36, 0x00, 0x31, 0x00, 0x42,
0x00, 0x43, 0x00, 0x30, 0x00, 0x30, 0x00 };
2-在打印消息中,长度等于sizeof(但是),但它是'char'(1字节)而不是'wchar_t'(2字节)。应该这样写:
std::wcout << "Hello" << std::wstring( (const wchar_t *)buf, (sizeof(buf) >> 1) ) << std::endl;
并且,这段代码给出了Windows PC上的预期结果…在您的计算机上管理'wchar_t'之前,请确保没有大/小端序转换。
你能检查一下Linux下的size (wchar_t)吗?这篇文章Linux和for的wchar_t的区别和转换Windows假定wchar_t是一个32位的值。
如果您遇到这个问题是因为您在Linux上遇到Unicode,宽字符和类似的问题,那么我发现前进的最快方法是使用libiconv。您将在c++文档中读到的<codecvt>
头文件尚未在GNU libstdc++中实现(截至2016年10月)。
下面是演示libiconv
的快速示例程序:
#include <iostream>
#include <locale>
#include <cstdint>
#include <iconv.h>
#include <string.h>
int
main( int, char ** )
{
const char a[] = "ABC";
const wchar_t b[] = L"ABC";
const char c[] = u8"ABC";
const char16_t d[] = u"ABCDEF";
const char32_t e[] = U"ABC";
iconv_t utf16_to_utf32 = iconv_open( "UTF-32", "UTF-16" );
wchar_t wcbuf[32];
char *inp = (char *)d;
size_t inl = sizeof(d);
char *outp = (char *)wcbuf;
size_t outl = sizeof(wcbuf);
iconv( utf16_to_utf32, &inp, &inl, &outp, &outl );
std::wcout << "sizeof(a) = " << sizeof(a) << ' ' << a << std::endl
<< "sizeof(b) = " << sizeof(b) << ' ' << b << std::endl
<< "sizeof(c) = " << sizeof(c) << ' ' << c << std::endl
<< "sizeof(d) = " << sizeof(d) << ' ' << d << std::endl
<< "sizeof(e) = " << sizeof(e) << ' ' << e << std::endl
<< "Converted char16_t to UTF-32: " << std::wstring( wcbuf, (wchar_t *)outp - wcbuf ) << std::endl;
iconv_close( utf16_to_utf32 );
return 0;
}
输出结果:
user@debian:~/code/unicode$ ./wchar
sizeof(a) = 4 ABC
sizeof(b) = 16 ABC
sizeof(c) = 4 ABC
sizeof(d) = 14 0x7ffefdae5a40
sizeof(e) = 16 0x7ffefdae5a30
Converted char16_t to UTF-32: ABCDEF
user@debian:~/code/unicode$
注意std::wcout不能正确打印char16_t或char32_t。但是,您可以使用iconv
将UTF-16(这显然是您从u"STRING"
获得的)转换为UTF-32(这显然与最新型号的Linux系统上的wchar_t
兼容)。
- 如何循环打印顶点结构
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 如何在c++中打印目录
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 在线编译器中的分段C++没有打印消息
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 如何将结构插入到集合中并打印集合的成员
- 在循环C++中指定字符串之后,不会打印该字符串
- 以螺旋方式打印矩阵的程序.(工作不好)
- 从控制台中删除最后打印的元素
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何仅使用对象名称打印特定于对象的成员
- 是否可以使用winusb同时与多个相同的usb设备进行通信
- 回溯C++不打印函数,因此文件
- 在一定长度后从数组中打印时缺少整数
- 为什么这个 c++ 代码打印出长度 5,当我打印出字符串时,程序会自动终止?
- 在gem5中打印文件中的所有cache_blocks
- 如何在c++中在cout/cerr上打印USB字符串描述符
- 是否可以在windows上使用Qt在网络usb打印机上逐行打印?