如果条件未按预期进行评估

时间:2016-09-30 17:22:37

标签: c#

我是Visual Studio和C#的新手,但我的问题似乎几乎是基本的,但我无法弄明白。我有一个二进制文件,我正在阅读,我试图一次或多或少地处理一个字节。问题是,当我在我的'中获得几个字节时,如果'条件似乎在它应该为FALSE之后很久就会评估为TRUE。

这里是输入二进制文件的快速列表,因此下面的代码是有意义的。

  

bytes [0-3]:前导码
  bytes [4]:消息类型
  bytes [5-7]:消息长度
  bytes [8-11]:测试ID

代码片段

      file = openFileDialog1.FileName;
      int byteLoc = 0;
      try
      {
           var bytes = File.ReadAllBytes(file);
           //loop through each byte from the input file
           foreach (var singleByte in bytes)
           {
                //Preamble - 4 bytes
                if (byteLoc < 4)
                {
                    preamble += Convert.ToString(singleByte);
                    preamble += " ";                        
                }
                //Message Type - 1 byte
                else if (byteLoc == 4)
                {
                    msgType += Convert.ToString(singleByte);
                }
                //Message Length - 3 bytes
                else if ((byteLoc > 4) || (byteLoc <= 7))
                {
                    msgLen += Convert.ToString(singleByte);
                    Console.WriteLine("Len:" + byteLoc);  //for debug
                }
                //Test ID - 4 bytes
                else if ((byteLoc >= 8) || (byteLoc <= 11))
                {
                    testID += Convert.ToString(singleByte);
                    Console.WriteLine("ID:" + byteLoc);   //for debug
                }
                byteLoc++;
           }
      }

我打印出了序言和msgType,它们按预期显示。然而,问题是,当我到达&#39; if&#39; msgLen的条件(应该是字节5-7),它总是评估为TRUE。我看到了消息&#34; Len:byteLoc&#34;从5开始,一直到文件的结尾。我在做错的是,当byteLoc到达8时,它不会转到下一个&#39;如果&#39;条件?

5 个答案:

答案 0 :(得分:2)

else if ((byteLoc > 4) || (byteLoc <= 7))
...
else if ((byteLoc >= 8) || (byteLoc <= 11))

这些应该&&而不是||

上面的第一个条件将始终评估为true(在之前的条件失败后),因为byteLoc将大于4.您需要使用AND约束它,而不是OR

条件(true OR false)将始终评估为真

答案 1 :(得分:2)

你的条件是byteLoc > 4 OR byteLoc <= 7,这将永远是真的。例如,11是大于4的数字,因此导致前半部分返回true,3是小于或等于7的数字,因此这将导致后半部分返回true。由于您使用的是OR,因此只有其中一个条件需要为整个条件才能返回true。

您希望使用&&代替||,因为您希望条件为byteLoc > 4 AND byteLoc <= 7。这将确保只有两个条件都成立时才能使整体状况成立。

答案 2 :(得分:2)

如上所述,问题在于您使用的是||(OR)而不是&&(AND),但由于您正在执行else if,因此您知道之前的条件是错误的,因此您只能使用上限检查。

if (byteLoc < 4)
{
    preamble += Convert.ToString(singleByte);
    preamble += " ";                        
}
//Message Type - 1 byte
else if (byteLoc == 4)
{
    msgType += Convert.ToString(singleByte);
}
//Message Length - 3 bytes
else if (byteLoc <= 7)
{
    msgLen += Convert.ToString(singleByte);
    Console.WriteLine("Len:" + byteLoc);  //for debug
}
//Test ID - 4 bytes
else if (byteLoc <= 11)
{
    testID += Convert.ToString(singleByte);
    Console.WriteLine("ID:" + byteLoc);   //for debug
}

答案 3 :(得分:2)

我知道这不是你要求的,但可能迭代所有字节并不是最好的解决方案。由于每种类型都有固定的字节数(前导码,消息类型,消息长度和testID)。你可以这样做:

        FileStream fs = File.OpenRead(@"C:\YourFilePath");
        BinaryReader br = new BinaryReader(fs);
        string preamble = Encoding.Default.GetString(br.ReadBytes(4));
        string msgType = br.ReadByte().ToString();
        string msgLen = Encoding.Default.GetString(br.ReadBytes(3));
        string testID = Encoding.Default.GetString(br.ReadBytes(4));

答案 4 :(得分:1)

if条件中的短路不正确:

else if((byteLoc&gt; 4)||(byteLoc&lt; = 7)) 对于大于4

的任何值,将返回true

改为:

else if ((byteLoc > 4) && (byteLoc <= 7))
其他分支的

等等