IndustProg
IndustProg

Reputation: 647

How to write switch statement for a string type?

I used a serial port to connect a device which returns to me ":GS#" string. After a long inspection, I am almost sure the problem is from switch condition, i.e., my program never enters cases and always goes to default. I printed the recieved string in a text box and it was ":GS#" ! I am confused. where is my mistake?

Here is my code:

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;

            }

        }

Upvotes: 1

Views: 498

Answers (2)

silver
silver

Reputation: 1703

change your string strRecieved initialization in the if statement to be:

strRecieved = new string(chars.TakeWhile(c => c != '\0').ToArray());

the issue is that the char array is holding multiple \0 characters at the end if the input is not length 8.

the following test demonstrate it:

[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);
    }

Upvotes: 1

Bojan B
Bojan B

Reputation: 2111

As it was pointed out in the comments your char array in which you save the read bytes is 8 characters long. So when you convert that array to a string it creates a string with the length of 8, you can check that by calling strRecieved.Length for example:

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

This means there are some non printable characters in the string (null by ASCII table). And therefore the case doesn't match!

Since the Read method of your serial port returns the number of bytes read try using that to get the correct substring. For example (I Think this should work):

char[] lxCMD = new char[8];
var bytesRead = 0; 
.
.
.

private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
  bytesRead = 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);
    strRecieved = strRecieved.SubString(0, bytesRead)
  }
  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;

            }

        }

Upvotes: 1

Related Questions