删除c#中的空格而不使用任何内置函数

时间:2014-04-02 00:46:13

标签: 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);

}

但我面临的问题是当我付出的时候 输入字符串为&#34; H e l&#34; 输出显示&#34; Hel l&#34; 这是因为最后一次迭代oldIndexarr[2]替换为arr[4]而最后一个字符&#39; l&#39;被遗漏了。有人可以指出正在做的错误吗? 注意:不应使用正则表达式,修剪或替换功能。 感谢。

4 个答案:

答案 0 :(得分:6)

a String constructor which allows you to control the length

所以只需将最后一行更改为

return new String(source, 0, newIndex);

请注意,.NET并不关心NUL字符(字符串可以很好地包含它们),因此您可以删除source[oldIndex] = '\0';,因为它无效。

答案 1 :(得分: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);
}

答案 2 :(得分:1)

您可以使用LINQ

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

你的错误是你正在移除空格,但你的源数组仍然包含剩余的chars。使用该逻辑你永远不会得到正确的结果,因为你没有删除任何东西,你只是替换了字符。你的while循环可以试试这个:

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

使用Take方法获取源数组的子集并忽略其余部分。

以下是另一种替代方式:

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

答案 3 :(得分:1)

你应该注意到很大程度上取决于你如何定义&#34;空白&#34;。 Unicode和CLR将空白定义为a rather exhaustive list of characterschar.IsWhitespace()对于很多字符都返回true。

&#34;经典&#34;空白的定义是以下字符: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的方法会明显慢于其他两种方法。但它很优雅。