繁体   English   中英

格式字符串从串行端口中删除或子字符串无一例外地如何?

[英]Format String remove or substring from Serial port without exception, how?

我正在使用这段代码来接收秤的重量。

对于.ToString一切都很好,但是当我调用.Remove(9, 5)它抛出了一个ArgumentOutOfRangeException 为什么? 我没有超出范围。

private delegate void Closure();

private void sport_DataReceived2(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
    if (InvokeRequired)     //<-- Makes sure the function is invoked to work properly in the UI-Thread
        BeginInvoke(new Closure(() => { sport_DataReceived2(sender, serialDataReceivedEventArgs); }));     //<-- Function invokes itself
    else
    {
        while (sport.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
        {
            textBox1.Text += string.Format("{0:X2} ", sport.ReadExisting().ToString().Remove(9, 5));
            //<-- bytewise adds inbuffer to textbox
        }
    }
}

我也尝试了一个子字符串,但仍然有异常。

整个接收的字符串是: "\\n00.394KG\\r\\nS00\\r"

因此,我必须使用remove或substring来获取我真正需要的内容-仅"00.394KG"部分。

如果这些是换行符和回车符,则可以使用String.Split

var result = "\n00.394KG\r\nS00\r".Split()[1];

这将创建一个大小为5的数组,其中第二项是您想要的项,即[1] 这样可以确保您不必担心值的长度。 另外,如果您获得的输入中没有至少一个空格字符,则应添加检查以确保该数组至少具有两个值。

但是,如果您的字符串确实是“ \\ n00.394KG \\ r \\ nS00 \\ r”,则.Remove .Remove(9,5)不会抛出您所指示的异常。 相反,您应该得到“ \\ n00.394KG \\ r”。 因此,我猜您实际上是一个较短的字符串,因此需要拆分。

一般来说,在运行时读取的字符串上使用Remove / Substring或任何其他与大小相关的方法是一个坏主意,因为您通常不控制字符串源的行为,并且如果该字符串与您期望的仅略有不同在编译时会遇到麻烦。

如果您进行如下测试,那么您的代码就是一个完美的例子:

Console.WriteLine("\n00.394KG\r\nS00\r".Remove(9, 5));

然后您可以看到调用remove并不是问题,但是您尝试使用的字符串与预期的有所不同。 可能是较短的字符串,因为这会产生ArgumentOutOfRangeException

一个安全的选择是在任何接收到的字符串上使用正则表达式,并且只有在该字符串符合正则表达式中编码的期望值时,才可以继续工作。

var recvString = sport.ReadExisting().ToString();
Regex readKGRx = new Regex(@"\n(\d{2}\.\d{3}KG)\r\nS00\r");
var readKGMatch = readKGRx.Match(recvString);
if (readKGMatch.Success) 
    textBox1.Text += string.Format("{0:X2}", readKGMatch.Groups[1].Value);
else 
    MessageBox.Show(string.Format("Bad string received: {0}", recvString));

如果您不知道如何使用正则表达式,则应至少将您的接收字符串存储为变量,并对它进行一些检查,然后再删除期望的内容。

string expectedFormat = "\n00.394KG\r\nS00\r";
var recvString = sport.ReadExisting().ToString();
bool formatCheckOK = true;
formatCheckOK = formatCheckOK && recvString.Length == expectedFormat.Length;
formatCheckOK = formatCheckOK && recvString[0] == expectedFormat[0];
formatCheckOK = formatCheckOK && recvString.IndexOf("KG") == expectedFormat.IndexOf("KG");
//more checks to be sure...
if (formatCheckOK) 
    textBox1.Text += string.Format("{0:X2}", recvString.Substring(1,8));
else 
    MessageBox.Show(string.Format("Bad string received: {0}", recvString));

尝试

sport.ReadExisting().ToString().Substring(2, 8)

它从第3个位置开始,持续8个字符,因此应返回所需的字符串。

我认为这不是使用.remove的最佳选择

sport.ReadExisting()。ToString()。SubString(9,5)

试试这个

寻找正则表达式解决方案。

var x = "\n00.394KG\r\nS00\r";
var match = Regex.Match(@"(?<serial>\d+\.\d+\w+)", x);
if (!match.Success) throw new FormatException(); // invalid format..
var serial = match.Groups["serial"].Value;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM