在给公司做网管程序的时候,由于公司的有些二层设备的设备名称有中文字符,而HP公司的snmp++在get的时候会显示中文为乱码。尝试在C#下将snmp++获得中文乱码字符串强制格式转换(java乱码的解决方案),可是没有搞定。没有办法了,只有改snmp++的源代码了,真是不看不知道,一看吓一跳。在hp的snmp_pp.doc,是这样描述snmp++中的字符串的,
When printing out an OctetStr object, the char * or get_printable() member functions automatically invoke the get_printable_hex() member function if the octet string contains any character which is non ASCII.
我们可以看到,snmp++只显示ascii字符.而ascii是单字节的,而中文字符是dbcs.好了找到了症结所在了,哈哈,在跑到snmp++的源代码上去看了一下,果然如此,下面是其源代码:
const char *OctetStr::get_printable() const
{
for (unsigned long i=0; i < smival.value.string.len; i++)
{
if ((smival.value.string.ptr[i] != '/r')&&
(smival.value.string.ptr[i] != '/n')
&& (isprint((int) (smival.value.string.ptr[i]))==0))
return get_printable_hex();
}
OctetStr *ncthis = PP_CONST_CAST(OctetStr*, this);
if (output_buffer_len < smival.value.string.len + 1)
{
if (output_buffer) delete [] ncthis->output_buffer;
ncthis->output_buffer = new char[smival.value.string.len + 1];
if (ncthis->output_buffer)
ncthis->output_buffer_len = smival.value.string.len + 1;
}
if (smival.value.string.len)
MEMCPY(ncthis->output_buffer,
smival.value.string.ptr, (unsigned int) smival.value.string.len);
ncthis->output_buffer[smival.value.string.len] = '/0';
return output_buffer;
}
它是用isprint函数来判断字符的合法性,而msdn中isprint()是判断单字节,所以遇到多姿节时会调用get_printable_hex(),得出16进制的字符串,从而出乱码,这样就有两种改进方案了.
一是:将判断直接删去,我就是这样做的,好像没有什么问题了,
二是:将
for (unsigned long i=0; i < smival.value.string.len; i++)
{
if ((smival.value.string.ptr[i] != '/r')&&
(smival.value.string.ptr[i] != '/n')
&& (isprint((int) (smival.value.string.ptr[i]))==0))
return get_printable_hex();
}
改为:
for (unsigned long i=0; i < smival.value.string.len; i++)
{
if ((smival.value.string.ptr[i] != '/r')&&
(smival.value.string.ptr[i] != '/n')
&& (isprint((int) (smival.value.string.ptr[i]))==0)
&& (iswprint((int) (smival.value.string.ptr[i]))==0))
return get_printable_hex();
}
我没有试验,不过我想这样也能搞定的