2010-04-05 52 views
12

我正在使用一個低級別的本地API,我發送一個不安全的字節緩衝區指針來獲取c-string值。幫助在C#中終止字符串0#

所以它給了我

// using byte[255] c_str 
string s = new string(Encoding.ASCII.GetChars(c_str)); 

// now s == "heresastring\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(etc)"; 

所以,很顯然我不這樣做是正確的,我該怎麼擺脫多餘的?

+0

當通過RS-232接收到字符串時,我得到了類似的東西。最終我做錯了:我發現爲接收到的每個字節調用處理程序,並在處理程序中使用'serialPortInstance.Read(...)'讀取多於1個字節。 – Dor 2010-04-05 21:59:23

+0

我不確定,但可能看看RegularExpression,像string re1 =「((?:[a-z] [a-z] +))」;並獲得第一個匹配 – 2017-03-24 20:37:07

+0

以null結尾的字符串的「規則」是,應該忽略以first null開頭的* everything *。 Trim()或Replace()的其他一些答案沒有考慮到在初始空值之後可能存在一些非空的「垃圾」。 [這個答案](https://stackoverflow.com/a/35182252/1633949)給出了一個單線解決方案。 – 2018-01-26 16:38:02

回答

0

我相信\ 0在ascii中爲「null」 - 你確定你得到的字符串實際上是ASCII編碼嗎?

+0

我認爲他意味着他得到一系列空字節,而不是他實際上得到「\ 0」字符串序列。 – Randolpho 2010-04-05 21:40:24

+0

是的,它的ASCII – y2k 2010-04-05 21:40:38

+0

我想我會做.Trim(「\ 0」)哈哈 – y2k 2010-04-05 21:43:18

5

可能有一個選項可以在轉換中剝離NUL。

除此之外,你也許可以用它清理乾淨:

s = s.Trim('\0'); 

...或者,如果你認爲可能會有一些完全無效後非NULL字符,這可能是更安全:

int pos = s.IndexOf('\0'); 
if (pos >= 0) 
    s = s.Substring(0, pos); 
28

.NET字符串不是空終止的(正如您可能已經猜到的那樣)。所以,你可以像對待任何普通字符那樣對待'\ 0'。正常的字符串操作將爲您解決問題。這裏有一些(但不是全部)選項。

s = s.Trim('\0'); 

s = s.Replace("\0", ""); 

var strings = s.Split(new char[] {'\0'}, StringSplitOptions.RemoveEmptyEntries); 

如果你一定要第一個空字符後扔掉的任何值,這可能爲你工作好。但要小心,它只適用於實際包含空字符的字符串。

s = s.Substring(0, Math.Max(0, s.IndexOf('\0'))); 
+0

這些方法錯過了字符串中第一個空值後可能有非空字符的事實。 [這個答案](https://stackoverflow.com/a/35182252/1633949)提供了一個更強大的解決方案。 – 2018-01-26 16:44:16

+0

嗯......這些方法中的任何一種如何在空值之後缺少字符?修剪僅適用於字符串的末尾。替換不會對字符串中除空字符以外的任何部分執行任何操作。拆分顯式保留除空字符以外的所有內容,生成一個字符串數組。它看起來像每個選項安全地處理任何字符串中的每個非空字符。 – 2018-01-29 04:56:32

+0

您的解決方案適用於OP提供的特定字符串。但是從本機(C++)API返回的字符串可能包含初始null後的垃圾。一般的解決方案必須忽略初始空值之後的所有內容,而不僅僅是省略null(s)。試試這個示例字符串上的每個解決方案(「這裏是一個字符串\ 0memoryjunkhere」)來查看我的意思。 – 2018-01-29 12:53:16

2

System.Runtime.InteropServices.Marshall.PtrToString*方法之一怎麼樣?

Marshal.PtrToStringAnsi - 將從非託管ANSI字符串到第一個空字符的所有字符複製到託管字符串,並將每個ANSI字符擴展爲Unicode。

Marshal.PtrToStringUni - 分配託管字符串並將全部或部分複製到非託管Unicode字符串的第一個空格中。

2
// s == "heresastring\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(etc)"  
s = s.Split(new[] { '\0' }, 2)[0]; 
// s == "heresastring"