C# 如何为字符串类型编写switch语句?
我使用一个串行端口连接一个设备,该设备返回给我“:GS#”字符串。经过长时间的检查,我几乎可以肯定问题出在哪里 切换条件,也就是说,我的程序从不输入cases,总是进入默认状态。我将收到的字符串打印在文本框中,结果是 “:GS#”!我很困惑。我的错在哪里 这是我的密码:C# 如何为字符串类型编写switch语句?,c#,winforms,switch-statement,C#,Winforms,Switch Statement,我使用一个串行端口连接一个设备,该设备返回给我“:GS#”字符串。经过长时间的检查,我几乎可以肯定问题出在哪里 切换条件,也就是说,我的程序从不输入cases,总是进入默认状态。我将收到的字符串打印在文本框中,结果是 “:GS#”!我很困惑。我的错在哪里 这是我的密码: char[] lxCMD = new char[8]; . . . private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataR
char[] lxCMD = new char[8];
.
.
.
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialPort.Read(lxCMD, 0, lxCMD.Length);
this.Invoke(new EventHandler(UpdateVar));
}
private void UpdateVar(object sender, EventArgs e)
{
string strRecieved = "Ack";
if (lxCMD[0] != 0x6)
{
strRecieved = new string(lxCMD);
}
textBox1.AppendText(strRecieved); // This line prints :GS# correctly!
textBox1.AppendText(Environment.NewLine);
switch(strRecieved)
{
case ":GS#":
serialPort.Write("20:08:18#");
textBox1.AppendText("1:");
textBox1.AppendText(Environment.NewLine);
break;
case "Ack":
serialPort.Write("1");
textBox1.AppendText("2:");
textBox1.AppendText(Environment.NewLine);
break;
default:
textBox1.AppendText("Nothing");
break;
}
}
正如注释中指出的那样,保存读取字节的
char
数组长度为8个字符。因此,当您将该数组转换为字符串时,它将创建一个长度为8的字符串,您可以通过调用strRecieved.length
来检查该字符串,例如:
textBox1.AppendText(strRecieved); // This line prints :GS# correctly!
textBox1.AppendText(Environment.NewLine);
Console.Out.WriteLine(strRecieved.Length); //or any other means of output - will output 8
这意味着字符串中有一些不可打印的字符(ASCII表为空)。所以这个案子不匹配
由于串行端口的Read
方法返回读取的字节数,请尝试使用该方法获取正确的子字符串。例如(我认为这应该有效):
将if语句中的字符串strRecieved初始化更改为:
strRecieved = new string(chars.TakeWhile(c => c != '\0').ToArray());
问题在于,如果输入的长度不是8,则char数组在结尾处包含多个\0字符
以下测试证明了这一点:
[Test]
public void stringConstructor_CharArrayWithSomeEmptyValues_StringWithoutEmptyValues()
{
var expected = "test";
var chars = new char[expected.Length+42];
chars[0] = expected[0];
chars[1] = expected[1];
chars[2] = expected[2];
chars[3] = expected[3];
var str = new string(chars.TakeWhile(c => c != '\0').ToArray());
Assert.AreEqual(expected, str);
str = new string(chars,0,chars.Length);
Assert.AreNotEqual(expected, str);
}
是否有任何控制字符添加到字符串中?也许你应该在切换前对其进行清理。字符串末尾是否有空格或不可打印字符?如果您的
char[]
长度为8个字符,则字符串也可能是该长度。除非您没有准确地接收到:GS#,否则没有理由认为该长度不起作用。检查未打印字符的字符串长度。我通过终端v1.93b进行了检查。十六进制字符串为3A 47 53 23,与“:GS#“@Pana”完全匹配-检查字符串的长度。NET不使用空终止字符串。它现在可以工作了!但有时bytesRead
的值为1,strecieved
的值为“:”然后bytesRead=3
和strecieved=GS
。为什么有时会有中断?是否有一些参数设置串行端口,以避免中断?
[Test]
public void stringConstructor_CharArrayWithSomeEmptyValues_StringWithoutEmptyValues()
{
var expected = "test";
var chars = new char[expected.Length+42];
chars[0] = expected[0];
chars[1] = expected[1];
chars[2] = expected[2];
chars[3] = expected[3];
var str = new string(chars.TakeWhile(c => c != '\0').ToArray());
Assert.AreEqual(expected, str);
str = new string(chars,0,chars.Length);
Assert.AreNotEqual(expected, str);
}