如何去除byte[]转string后自动添加的\0\0\0\0\0\0\0\

push_chen1984 2017-05-24 10:26:36
各位高手想请教一个问题,我在做海康dvr设备的二次开发,遇到了一个byte[]转string的问题,
sChanNameTemp = System.Text.Encoding.GetEncoding("GBK").GetString(m_struPicCfgV40.sChanName);
sChanNameTemp为string类型,获取了当前通道的名称,在之后的代码里会将通道名称与自定义的前缀合并成新的通道名称,但是现在sChanNameTemp获取的值里每次都会自动补一堆\0\0\0\0\0\\0\0\0\0...
我想问的是2点,1 怎么样才能不要让它自动生成这些\0\0\0\0\,2如果1不行,那有什么办法可以删除这些不需要的东西,sChanNameTemp里存放的内容是中文和符号混合的
...全文
1636 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
push_chen1984 2017-05-26
  • 打赏
  • 举报
回复
谢谢大家的启发,我看了以后也觉得要彻底搞明白这个bug还是要从m_struPicCfgV40.sChanName到底有多少有用数据入手,基本方向了解了,再次谢谢大家,那我先结帖了
  • 打赏
  • 举报
回复
说明 m_struPicCfgV40.sChanName 中有效字符到底是多少个 --> 说明 m_struPicCfgV40.sChanName 中有效字节到底是多少个 通常制定跨语言协议应该考虑各种语言的通用规则。但是一些 c 程序员只知道按照 c 的规则行事,并不通用。
  • 打赏
  • 举报
回复
就像 #5 楼所说,假设 buffer 一共有1000字节大小,但是最后有连续 600个 \0,那么你自然是要调用 GetString(buffer, 0, buffer.Length-600) 而不是调用 GetString(buffer) 了。 正常情况下,一个二进制协议中会有一个字段来说明 m_struPicCfgV40.sChanName 中有效字符到底是多少个。 最初的 c 语言字符串规范是以第一个 \0 为字符串截断符号的,那么你在明知道对方是纯 c 语言的规范时也可以这样来判断。 总之是按照有依据的原理来准确识别出真实的不冗余的数据。而不是自己随便 Replace 或者 Trim。
wanghui0380 2017-05-25
  • 打赏
  • 举报
回复
在微软的框架里pinvoke部分因为要兼容传统的语言,所以都会采用只提取第一个\0的之前的byte 比如 Marshal.PtrToStringAnsi 这个就是 当然微软早期只写了 Marshal.PtrToStringAnsi Marshal.PtrToStringUni 后来加了 Marshal.PtrToStringUTF8 不过俺们很多情况会要其他编码,所以我们只好自己扩展出10那种看上去很别扭的代码了
wanghui0380 2017-05-25
  • 打赏
  • 举报
回复
  public static string PtrToString(IntPtr ptr,Encoding encode)
        {

            List<byte> lb = new List<byte>();
            while (Marshal.ReadByte(ptr) != 0)
            {
                lb.Add(Marshal.ReadByte(ptr));
                ptr = ptr + 1;
            }
            byte[] bs = lb.ToArray();
            return encode.GetString(lb.ToArray());
        }
当然你需要先得到byte[]的inptr
crystal_lz 2017-05-24
  • 打赏
  • 举报
回复
System.Text.Encoding.XXXX.GetString() 不只是一个重载还有(byte[] data.int Index,int count)这样的方式 还有是什么函数向你的m_struPicCfgV40.sChanName填入数据的?难道他都没有向你返回都少数据被填入吗?如果说有 那就是你的问题 给你返回了长度你不用 如果没有那么我就只能呵呵呵了 设计那个函数的人也是挺牛逼的
xuggzu 2017-05-24
  • 打赏
  • 举报
回复
转字符串用于显示或其它可以trim或replace,也可以转之前将byte数组中的多余空字节去掉再转字符串。

再传参数出错,那就还是用原btye数组,不要传转换后的字符串。其实这和你用法有关,不能一概而论,必须根据实际情况来取舍方案。
水哥阿乐 2017-05-24
  • 打赏
  • 举报
回复
如果有条件找找厂商的示例文档, 看看原理,这才是最重要的弄清楚为什么会在替换后出现A ,出现\0这种情况非常好办,普通的Replac方法和正则替换都可以达到要求,不用纠结于替换方法
push_chen1984 2017-05-24
  • 打赏
  • 举报
回复
trim去不掉,还是会传到下一个引用处然后报错 byte[] byName = System.Text.Encoding.Default.GetBytes(x.Cells[4].Value.ToString() +"-"+ sChanNameTemp); m_struPicCfgV40.sChanName = new byte[32];//这里默认长度是32,但是上面那句光sChanNameTemp就给我占满32了,然后直接报长度溢出 byName.CopyTo(m_struPicCfgV40.sChanName, 0);
xdashewan 2017-05-24
  • 打赏
  • 举报
回复 2
\0是c里的结束符,c#string可以接收但不会有任何显示,你一定要去掉可以用TrimEnd('\0')或者replace掉
xuzuning 2017-05-24
  • 打赏
  • 举报
回复
byte[] 尾部有多余的空元素,如果没有辅助的有效数据长度信息,不好明确删除 生成字符串后,可用 Trim 方法去除
  • 打赏
  • 举报
回复
不要 Replace 或者 Trim。
  • 打赏
  • 举报
回复
m_struPicCfgV40.sChanName 本身就不是文字的准确内容,填充了一堆冗余字节的多余缓冲区。如果你没有能够得到对方传来的这个缓冲区中有效数据长度信息(按说这通常是你理解上的bug,对方很可能已经传来了),那么你可以先把 m_struPicCfgV40.sChanName 末尾的 \0 一共有多少个计算出来,再使用这个信息来调用 GetString 方法。
push_chen1984 2017-05-24
  • 打赏
  • 举报
回复
谢谢大家,现在的情况是这样的,我找到了一个解决方案,但是貌似有奇怪的bug,这个bug出现的次数很少,至少我现有的测试中出现的不多,我很困惑,先看解决方案吧: sChanNameTemp = System.Text.Encoding.GetEncoding("GBK").GetString(m_struPicCfgV40.sChanName); //sChanNameTemp.TrimEnd("\0");//直接这样转换不行 //doubletemp=sChanNameTemp.Trim("\0".ToCharArray());//再设置一个string类型的变量二传一下可以了,但是有时会出现末尾多一个A doubletemp =sChanNameTemp.Replace("\0","");//一样可用,但是不定时会出现末尾自动加一个A 之所以要这样折腾是因为,我需要的功能是要先获取硬件设备内的文字内容(byte[]格式,中文与符号混合),然后在把一个string类型的自定义前缀文字内容与它结合组成新的文字内容再转回硬件可以接受的byte[]格式:

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧