2014-04-02 27 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的方法会明显慢于其他两个。虽然它很优雅。