2016-09-30 3 views
1

Я новичок в Visual Studio и C#, но моя проблема кажется почти элементарной, но я не могу понять это. У меня есть двоичный файл, который я читаю, и я пытаюсь обработать его более или менее байт за раз. Проблема в том, что когда я получаю несколько байтов в моем состоянии «если», кажется, что значение TRUE долгое время должно быть FALSE.Если условие не оценивается как ожидалось

Вот быстрый jist входного двоичного кода, поэтому приведенный ниже код имеет смысл.

байт [0-3]: Преамбула
байт [4]: ​​тип сообщения
байт [5-7]: длина сообщения
байт [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 и они появляются, как ожидалось. Однако проблема заключается в том, что когда я перехожу к условию «if» для msgLen (который должен быть байтами 5-7), он ВСЕГДА оценивает значение TRUE. Я вижу сообщение «Len: byteLoc», начинающееся с 5 и идущее до конца файла. Что я делаю неправильно здесь, когда byteLoc достигает 8, а не переходит в следующее условие «если»?

+0

Вы должны использовать '&&' вместо '||'. Все больше 4 или меньше 7. – juharr

+0

Подсказка: если 'byteLoc == 47', что' bytLoc> 4' оценивает? – CDspace

+0

Каждое целое число существует * либо * больше четырех, * или * меньше или равно семи. 5, 6 и 7 - оба. –

ответ

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 
} 
+0

Отличное предложение. Благодаря! – milnuts

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

Они должны быть && вместе, а не ||

Ваше первое условие выше всегда будет оценивать истинным (после того, как провалил предыдущие условия), потому что byteLoc будет больше чем 4. Вы должны ограничить его AND, не OR

условия (true OR false) всегда будет оценивать истинные

+0

Сладкая милость, я идиот. Это то, что происходит, когда вы слишком долго смотрите на один и тот же код. Благодарю. – milnuts

2

Вашего состояния byteLoc > 4 OR byteLoc <= 7, который всегда будет правдой. Например, 11 - это число, большее 4, поэтому первая половина возвращает true, а 3 - число, меньшее или равное 7, так что вторая половина вернет значение true. Поскольку вы используете OR, только одно из условий должно быть истинным для всего условия, чтобы вернуть true.

Вы хотите использовать && вместо ||, так как вы хотите, чтобы ваше состояние было byteLoc > 4 AND byteLoc <= 7. Это гарантирует, что общее условие будет истинным только в том случае, если оба условия верны.

1

Короткое замыкание в если условие неверно:

иначе, если ((byteLoc> 4) || (byteLoc < = 7)) возвращает истину для любого значения больше, что 4

сделать вместо:

else if ((byteLoc > 4) && (byteLoc <= 7)) 

и т.д. и т.д. для других отраслей либо еще

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)); 
+0

Это намного чище. Я могу сделать это. Благодаря! – milnuts

Смежные вопросы