【问题标题】:Expand C# string with control characters用控制字符展开 C# 字符串
【发布时间】:2014-03-03 12:56:37
【问题描述】:

我需要在条形码扫描中扩展控制字符(不可打印)。

这就是我所拥有的。目前,我对如何从输入字符串的子字符串中获取整数索引感到困惑。

    // A method for expanding ASCII Control Character into Human Readable format
    string ExpandCtrlString(string inStr)
    {
        // String Builder Capacity may need to be lengthened...
        StringBuilder outStr = new StringBuilder(128);
        // 0 Based Array representing the expansion of ASCII Control Characters
        string[] CtrlChars = new string[]
        {
            "<nul>",
            "<soh>",
            "<stx>",
            "<etx>",
            "<eot>",
            "<enq>",
            "<ack>",
            "<bel>",
            "<bs>",
            "<tab>",
            "<lf>",
            "<vt>",
            "<ff>",
            "<cr>",
            "<so>",
            "<si>",
            "<dle>",
            "<dc1>",
            "<dc2>",
            "<dc3>",
            "<dc4>",
            "<nak>",
            "<syn>",
            "<etb>",
            "<can>",
            "<em>",
            "<sub>",
            "<esc>",
            "<fs>",
            "<gs>",
            "<rs>",
            "<us>"
        };

        for (int n = 0; n < inStr.Length; n++)
        {
            if (Char.IsControl(inStr, n))
            {
                //char q = inStr.Substring(n, 1);
                int x = (int)inStr[n] ();
                outStr.Append(CtrlChars[x]);
            }
            else
            {
                outStr.Append(inStr.Substring(n, 1));
            }
        }
        return outStr.ToString();
    }

编辑: 想着想着就想到了……

我对子字符串进行了双重转换,它起作用了......

那是我选了演员... :)

    for (int n = 0; n < inStr.Length; n++)
    {
        if (Char.IsControl(inStr, n))
        {
            int x = (int)(char)inStr[n];
            outStr.Append(CtrlChars[x]);
        }
        else
        {
            outStr.Append(inStr.Substring(n, 1));
        }
    }
    return outStr.ToString();

而且,它适用于 Windows Mobile 5 的 CF NET 2.0

我曾考虑过使用 foreach,但是,这给 VB6 的老家伙带来了其他问题。 :)

【问题讨论】:

  • 乍一看,代码看起来不错。什么不工作? inStr[n] () 是错字吗?大括号不应该在那里。
  • @SamLeach .. 虽然我同意您对文本组件的编辑,但我认为编辑问题本身的代码并不符合问题的最佳利益。恕我直言,这减损了我们对 OP 来自何处的理解,使其他评论员先前所做的陈述无效,而且代码仍然存在缺陷。如果你想指出 OP 哪里错了,那么答案就是它的赌注。

标签: c# string substring stringbuilder


【解决方案1】:

字符可以像数字一样使用。这是一个更简单的循环:

foreach (char c in inStr)
{
    // Check to see if c (as a number here) is less than the CtrlChars array size
    // If it is, then print the CtrlChars text
    if (c < CtrlChars.Length)   
    {
        outStr.Append(CtrlChars[c]);
    }
    else
    {
        outStr.Append(c);
    }
}

【讨论】:

  • 我曾考虑过使用 foreach... 但是,由于我不明白到底发生了什么:if (c
  • 好的。添加了注释来解释。基本上它说如果 c 小于 33,则打印 CtrlChars 文本。
  • 啊...我错过了! :) 谢谢!
【解决方案2】:

我可以看到您的方法来自哪里,但我也可以看到您尝试做的事情中的一些缺陷。

首先..我在做这个没有测试..所以买家要小心!

其次,来自微软的Char.IsControl Method (String, Int32)The Unicode standard assigns code points from \U0000 to \U001F, \U007F, and from \U0080 to \U009F to control characters. 您的数组并未涵盖所有这些范围,因此可能(取决于您的字符串的来源)您的代码实际上会爆炸,因为您将提供一个索引超出了数组的范围。这可以通过使用字典将数字映射到字符串而不是数组来解决。

dictionary<int, string> mapping = new dictionary<int, string>() {
  { 0, "<nul>" },
  { 1, "<soh>"  },

  .. etc filled with every possible control char
}

请注意,该字典确实应该在包含ExpandCtrlString 方法的 中定义/构造,而不是在方法本身中。

class expand
{
   private dictionary<int, string> mapping …

   public string ExpandCtrlString(string inStr)
   {
     ...
    }

}

要得到你的字符,你可以简单地做:

for (int n = 0; n < inStr.Length; n++)   
{
    char ch = instr[n];
    ...
}

或者如果你想更现代,你可以直接从字符串中获取字符:

foreach(var ch in instr)
{
    ...
}

然后检查char是否为控制char,如果是则在字典中

if (Char.IsControl(ch))
{
    // The value is not needed until you know its a control char
    int val = (int)Char.GetNumericValue(ch);

    if (mapping.ContainsKey(val))
    {
        // You know what the control char is, so output its name
        outStr.Append(mapping[val]);
    }
    else
    {
       // You might have missed a control char in your dictionary of names
       // So by default output its hex value instead
       outStr.AppendFormat("<{0}>", val.ToString("X"));  
    }
}
else
{
    // Char is not a control char
    outStr.Append(ch);
}

然后最后像你已经做的那样返回你的 outStr。

【讨论】:

  • 虽然有从 80 到 9F 的第二级 Unicode 控制字符,但条形码扫描仪不会,AFAIK,输出任何高于 ASCII 127 的内容。但是,我会意识到这种可能性。此外,通过使用 Switch 语句,任何未在 switch 案例中特别涉及的内容都将落入 Default 语句。所以,现在我应该没事。感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 2015-02-16
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多