C# 将包含 c 样式字符串的 byte[] 转换为 NOT Encoding.GetString(byte[])

本文关键字:byte NOT Encoding GetString 转换 字符串 样式 包含 | 更新日期: 2023-09-27 17:55:58

愚蠢的我试图将从外部源接收的字节数组转换为字符串,而不是我的控制。(是的,我确实知道Encoding.GetString(byte[]).

到目前为止,我拥有的:

void myfunc()
{
    byte[] rawData = new byte[ 128 ];
    for( int i = 0; i < rawData.Length; ++i )
    {
        rawData[ i ] = 0;
    }
    rawData[ 0 ] = (byte)'H';
    rawData[ 1 ] = (byte)'e';
    rawData[ 2 ] = (byte)'l';
    rawData[ 3 ] = (byte)'l';
    rawData[ 4 ] = (byte)'o';

    string asString = Encoding.UTF8.GetString( rawData, 0, rawData.Length );
    string asRealString = Encoding.UTF8.GetString( rawData );
}

两个字符串都包含 Hello 部分,但之后也包含很多 ''0 - 这不是我所期望的。调试器的输出:作为实数字符串 =

"Hello'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0'0"

有什么办法可以给我一个像"你好"这样的字符串?

我做了咕噜咕噜,但我得到的只是Encoding.GetString(byte[])...

编辑:字节数组的创建超出了我的范围!我确实把它作为一个更大的 C 风格结构的一部分。并且字符串没有前导长度。我也希望有内置的 ome 来做它,我不必找到第一个 ''o 和 tehn 转换知道长度......

编辑这是我最后使用的:

private static string convertCString( byte[] buffer, int maxLength, Encoding targetEncoding )
{
    int length = 0;
    int realMax = buffer.Length < maxLength ? buffer.Length : maxLength;
    for( 
         ; 0 != buffer[length] && length < realMax
         ; ++length )
    {}
    return targetEncoding.GetString( buffer, 0, length );
}

C# 将包含 c 样式字符串的 byte[] 转换为 NOT Encoding.GetString(byte[])

只需找到第一个0

    int len = Array.IndexOf(rawData, (byte)0); // maybe some bounds check too
    string asString = Encoding.UTF8.GetString(rawData, 0, len);

尝试

Encoding.UTF8.GetString( rawData ).Trim();

字节数组的创建超出了我的范围!我确实把它作为一个更大的 C 风格结构的一部分。并且字符串没有前导长度。

可以通过

让编组器为您执行此操作,以内置方式执行此操作。

我假设你现在拥有的是这样的:

struct CStruct
{
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)]
  public byte[] data;
}

尝试将其更改为:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct CStruct
{
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
  public string data;
}

你为什么没想到呢?您明确告诉它首先要这样做:

byte[] rawData = new byte[ 128 ];
for( int i = 0; i < rawData.Length; ++i )
{
    rawData[ i ] = 0;   // RIGHT HERE
}

上面的代码创建一个 128 项字节数组,for 循环填充它。然后,代码显式更改前 5 个字节的值。如果您不想看到 ''0,那么您需要在将其发送到 GetString 之前不要将其放在那里或将其从数组中排除。

当你这样做时

string asString = Encoding.UTF8.GetString( rawData, 0, rawData.Length );

与其传入rawData.Length,不如只传入字符串的实际长度吗?

new string(Array.ConvertAll(rawData, x => (char)x))
字符串

构造函数将在第一个 ''0 处终止字符串。

void myfunc()
{
    byte[] rawData = new byte[ 128 ];
    //CLR will initialize each elemnet in arry to the 0
    //for( int i = 0; i < rawData.Length; ++i )
    //{
    //    rawData[ i ] = 0;
    //}
    rawData[ 0 ] = (byte)'H';
    rawData[ 1 ] = (byte)'e';
    rawData[ 2 ] = (byte)'l';
    rawData[ 3 ] = (byte)'l';
    rawData[ 4 ] = (byte)'o';
    // you should know length of the received string (each IO read method return number of read bytes), if you don't know it you can try to search 0 as the EOS
    var receivedBytes = Array.IndexOf(rawData, 0);
    string asString = Encoding.ASCII.GetString( rawData, 0, receivedBytes );
}