2014-04-02 30 views
0

嗨,我是C#的初學者,我試圖刪除字符串中的空格。 我使用下面的代碼:刪除c#中的空格,沒有任何內置的函數

public String RemoveSpace(string str1) 
{ 

    char[] source = str1.ToCharArray(); 

    int oldIndex = 0; 
    int newIndex = 0; 
    while (oldIndex < source.Length) 
    { 
     if (source[oldIndex] != ' ' && source[oldIndex] != '\t') 
     { 
      source[newIndex] = source[oldIndex]; 
      newIndex++; 
     } 
     oldIndex++; 
    } 
    source[oldIndex] = '\0'; 
    return new String(source); 

} 

但我面臨的問題是,當我給 輸入字符串爲「H EL」 的輸出顯示「赫爾L」 這是因爲在最後一次迭代oldIndexarr[2]arr[4]取代,最後一個字符'l'被省略。有人能指出正在犯的錯誤嗎? 注意:不應該使用正則表達式,修剪或替換函數。 謝謝。

+1

我想你的意思是說'source [newIndex] ='\ 0'' – AndyG

+1

@AndyG:這將避免IndexOutOfRangeException,但它不會截斷字符串。 –

+0

該代碼導致大量的更正 – prabhakaran

回答

2

一些學習要點:

  • 增量連接字符串是比較慢的。既然你知道你將要做一個'很多'(不確定)的逐個字符的操作,使用一個char數組作爲工作字符串。
  • 迭代字符的最快方法是C#使用內置的字符串索引器。

如果您需要檢查其他字符,除了空格,製表符,回車,換行,然後在if語句添加附加條件:

public static string RemoveWhiteSpace(string input) { 
    int len = input.Length; 
    int ixOut = 0; 
    char[] outBuffer = new char[len]; 
    for(int i = 0; i < len; i++) { 
     char c = input[i]; 
     if(!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) 
      outBuffer[ixOut++] = c; 
    } 
    return new string(outBuffer, 0, ixOut); 
} 
+0

他已經在做你的要點提到的兩件事情。 'Array.Resize'是修剪結束的一種可行的方式,但它也會產生額外的不需要的副本。 –

+0

不,他不做第二件事。他調用了「ToCharArray」,它在輸入字符串中創建了所有字符的新副本*。我直接索引到字符串中,該字符串返回字符而不創建(輸入的)字符數組。 –

+0

的確如此,但他並沒有創建* extra *數組。 'ToCharArray()'的結果是他的工作數組。 –

1

您可以使用LINQ爲:

var output = new string(input.Where(x => !char.IsWhiteSpace(x)).ToArray()); 

你的錯誤是您要刪除的空間,但你的源陣列仍包含剩餘chars。採用這種邏輯,你將永遠不會得到正確的結果,因爲你不消除任何,你只是更換chars.After你while循環,可以試試這個:

return new String(source.Take(newIndex+1).ToArray()); 

使用Take方法讓你的源陣列和IG的子集其餘的都是其他人。

這裏是這樣做的另一個替代方式:

var output = string.Concat(input.Split()); 
+1

這是作業。如果OP是學習代碼,我不認爲LINQ請求會幫助他。 – aloisdg

+0

@aloisdg:當然是作業了。但是我們完全不知道問題是什麼。這很可能是:想出一種方法來刪除字符串中的空格。如果是的話,那麼這個答案和我的提供兩個選擇,都使用框架的力量...沒有使用正則表達式,修剪或替換 – NotMe

+0

@aloisdg我同意。我會盡量根據要求更新我的答案...... –

6

a String constructor which allows you to control the length

所以才最後一行改爲

return new String(source, 0, newIndex); 

注意.NET不關心關於NUL字符(字符串可以包含它們就好),所以你可以刪除source[oldIndex] = '\0';,因爲它是ine ffective。

+1

更好。到目前爲止OPs原始代碼的最簡單的改變。 – NotMe

+0

@BenVoigt它的作品像魅力。感謝您的幫助... – user1561245

1

你應該注意到,在很大程度上取決於你如何定義「空白」。 Unicode和CLR將空白字符定義爲a rather exhaustive list of characterschar.IsWhitespace()對於很多字符都返回true。

空白的「經典」定義是以下字符:HT,LF,VT,FF,CR和SP(有些可能還包括BS)。

我自己,我可能會做這樣的事情:

public static class StringHelpers 
{ 
    public static string StripWhitespace(this string s) 
    { 
    StringBuilder sb = new StringBuilder() ; 
    foreach (char c in s) 
    { 
     switch (c) 
     { 
    //case '\b' : continue ; // U+0008, BS uncomment if you want this 
     case '\t' : continue ; // U+0009, HT 
     case '\n' : continue ; // U+000A, LF 
     case '\v' : continue ; // U+000B, VT 
     case '\f' : continue ; // U+000C, FF 
     case '\r' : continue ; // U+000D, CR 
     case ' ' : continue ; // U+0020, SP 
     } 
     sb.Append(c) ; 
    } 
    string stripped = sb.ToString() ; 
    return stripped ; 
    } 
} 

你可以使用正是如此你的方法。然而,這對READ THE DOCUMENTATION重要):你會注意到使用string構造函數重載,讓您的數組作爲字符串初始化向量中指定一個範圍:

public static string StripWhitespace(string s) 
{ 
    char[] buf = s.ToCharArray() ; 
    int j = 0 ; // target pointer 
    for (int i = 0 ; i < buf.Length ; ++i) 
    { 
    char c = buf[i] ; 
    if (!IsWs(c)) 
    { 
     buf[j++] = c ; 
    } 
    } 
    string stripped = new string(buf,0,j) ; 
    return stripped ; 
} 

private static bool IsWs(char c) 
{ 
    bool ws = false ; 
    switch (c) 
    { 
//case '\b' : // U+0008, BS uncomment if you want BS as whitespace 
    case '\t' : // U+0009, HT 
    case '\n' : // U+000A, LF 
    case '\v' : // U+000B, VT 
    case '\f' : // U+000C, FF 
    case '\r' : // U+000D, CR 
    case ' ' : // U+0020, SP 
    ws = true ; 
    break ; 
    } 
    return ws ; 
} 

你也可以使用LINQ的,東西像:

public static string StripWhitespace(this string s) 
    { 
     return new string(s.Where(c => !char.IsWhiteSpace(c)).ToArray()) ; 
    } 

雖然,我願意Linq的方法會明顯慢於其他兩個。雖然它很優雅。