将字节数组转换为String时修剪填充值

时间:2017-03-08 16:57:44

标签: c# string

我在C#程序中使用的外部DLL为我提供了指向内存中某个位置的指针。从那里,我在该位置读取以下200字节的字节数组,然后将其转换为字符串。

问题:在大多数情况下,我的代码可以工作,但它也会读取DLL用作填充的值(似乎是205)。

尝试:我尝试使用此Stack Overflow post中的示例修剪字符串,但填充仍然存在。我的代码如下:

const int BYTES_PER_DEVICE_NAME = 200;
const char PADDING_VALUE = (char)205;
const char NULL_VALUE = (char)0;

IntPtr nameAddress = (IntPtr)myDLL.GetPointer();

// Only run if the pointer is not to a null value
if (nameAddress != IntPtr.Zero)
{
    byte[] nameAsBytes = new byte[BYTES_PER_DEVICE_NAME];
    Marshal.Copy(nameAddress, nameAsBytes, 0, BYTES_PER_DEVICE_NAME);
    string nameAsString = System.Text.Encoding.UTF8.GetString(nameAsBytes).TrimEnd(new char[] { PADDING_VALUE, NULL_VALUE });

    // Add the string to deviceNames, a string array
    deviceNames[n] = nameAsString;
}

如下所示,即使我使用TrimEnd(),字符串nameAsString仍然最终包含空值和填充值。

Padded values in a String

我目前正在尝试查看是否可以在\0字节数组中找到nameAsBytes的索引,并且只解析字节直到该索引。但是,我对TrimEnd()做错了什么?

2 个答案:

答案 0 :(得分:2)

一旦字节数组转换为.NET字符串,它就是UTF16编码,而char(205)将没有你想要的效果。任何大于127的值都可能最终映射到转换后的不同代码点。

尝试在转换为字符串之前删除205的

const int BYTES_PER_DEVICE_NAME = 200;
const char PADDING_VALUE = (char)205;
const char NULL_VALUE = (char)0;

IntPtr nameAddress = (IntPtr)myDLL.GetPointer();

// Only run if the pointer is not to a null value
if (nameAddress != IntPtr.Zero)
{
    byte[] nameAsBytes = new byte[BYTES_PER_DEVICE_NAME];
    Marshal.Copy(nameAddress, nameAsBytes, 0, BYTES_PER_DEVICE_NAME);
    byte[] cleanedBytes = nameAsBytes.Where(a => a != PADDING_VALUE); //Filter out the bad bytes
    string nameAsString = System.Text.Encoding.UTF8.GetString(cleanedBytes);

    // Add the string to deviceNames, a string array
    deviceNames[n] = nameAsString;
}

答案 1 :(得分:1)

您可以使用UTF8Encoding.GetString方法(Byte [],Int32,Int32)方法:https://msdn.microsoft.com/en-us/library/kzb9f993(v=vs.110).aspx

byte[] nameAsBytes = new byte[BYTES_PER_DEVICE_NAME];
Marshal.Copy(nameAddress, nameAsBytes, 0, BYTES_PER_DEVICE_NAME);
int strlen;
for (strlen = 0; strlen < nameAsBytes.Length;strlen++)
{
  if (nameAsBytes[strlen] == 0)
    break;
}
string nameAsString = System.Text.Encoding.UTF8.GetString(nameAsBytes, 0, strlen);