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 );
}
只需找到第一个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 );
}