2013-04-29 10 views
5

Ho un array di byte che sembra qualcosa di simile:Come cercare correttamente e analizzare un array usando una sequenza di elementi come destinazione

byte[] exampleArray = new byte[] 
         { 0x01, 0x13, 0x10, 0xe2, 0xb9, 0x13, 0x10, 0x75, 0x3a, 0x13 }; 

Il mio obiettivo finale è quello di dividere questo array in qualsiasi momento sotto di serie I vedere la sequenza { 0x13, 0x10 }. Quindi il mio risultato desiderato sull'esempio serie sarebbe:

{ 0x01 } 
{ 0xe2, 0xb9 } 
{ 0x75, 0x3a, 0x13 } 

Idealmente, avrei anche bisogno di sapere che l'array finale, { 0x75, 0x3a, 0x13 }, non si è concluso con la sequenza di ricerca in modo che ho potuto lavorare con che come una speciale Astuccio.

Qualche idea sull'approccio migliore?

+0

Cosa succede se si converte la matrice della stringa ascii e si utilizza string.split? Qualcosa come 'Encoding.ASCII.GetString (exampleArray) .Split (...)' – Vladimir

+0

Vedi questo: http://stackoverflow.com/a/4617264/848330 – nmat

+1

'string delimiter = Encoding.ASCII.GetString (new byte [ ] {0x13, 0x10}); ' – Vladimir

risposta

1
List<byte[]> Split(byte[] bArray) 
     { 
      List<byte[]> result = new List<byte[]>(); 
      List<byte> tmp = new List<byte>(); 
      int i, n = bArray.Length; 
      for (i = 0; i < n; i++) 
      { 
       if (bArray[i] == 0x13 && (i + 1 < n && bArray[i + 1] == 0x10)) 
       { 
        result.Add(tmp.ToArray()); 
        tmp.Clear(); 
        i++; 
       } 
       else 
        tmp.Add(bArray[i]); 
      } 
      if (tmp.Count > 0) 
       result.Add(tmp.ToArray()); 
      return result; 
     } 

L'ultima serie non può terminare con la sequenza, qualsiasi parte Splited non separa il separatore. Può accadere solo il byte 0x13, quindi se questo è importane per voi, è possibile controllare l'ultimo byte dell'ultimo sub array.

+0

Ciò comporterà errori indice fuori limite; è necessario assicurarsi che il ciclo 'for' non vada fino in fondo se si controlla l'elemento" successivo "all'interno del corpo. – Servy

+0

Ho accettato questa risposta in quanto è la più vicina a quello che ho finito per fare. Grazie. –

1

Che ne dite di qualcosa come questo che dovrebbe funzionare nel caso generale (ovviamente con una migliore controllo degli errori!):

using System; 
using System.Collections.Generic; 
using System.Linq; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     byte[] exampleArray = new byte[] { 1, 2, 3, 4, 5, 2, 3, 6, 7, 8 }; 

     var test = exampleArray.PartitionBySubset(new byte[] { 2, 3 }).ToList(); 
    } 
} 

public static class Extensions 
{ 
    public static IEnumerable<IEnumerable<T>> PartitionBySubset<T>(this IEnumerable<T> sequence, IEnumerable<T> subset) where T : IEquatable<T> 
    { 
     // Get our subset into a array so we can refer to items by index and so we're not iterating it multiple times. 
     var SubsetArray = subset.ToArray(); 
     // The position of the subset array we will check 
     var SubsetArrayPos = 0; 
     // A list to hold current items in the subsequence, ready to be included in the resulting sequence 
     var CurrentList = new List<T>(); 

     foreach (var item in sequence) 
     { 
      // add all items (ones part of the subset will be removed) 
      CurrentList.Add(item); 
      if (item.Equals(SubsetArray[SubsetArrayPos])) 
      { 
       // This item is part of the subset array, so move to the next subset position 
       SubsetArrayPos++; 
       // Check whether we've checked all subset positions 
       if (SubsetArrayPos == SubsetArray.Length) 
       { 
        // If so, then remove the subset items from the current list 
        CurrentList.RemoveRange(CurrentList.Count - SubsetArray.Length, SubsetArray.Length); 
        // Reset the position 
        SubsetArrayPos = 0; 

        // Only return the list if it's not empty (the main list could start with a subset) 
        if (CurrentList.Count != 0) 
        { 
         // Return the list we have now since it's been ended. 
         yield return CurrentList; 
         // Create a new list ready for more items 
         CurrentList = new List<T>(); 
        } 
       } 
      } 
      else 
      { 
       // This item isn't part of the subset, so next time check the start. 
       SubsetArrayPos = 0; 
      } 
     } 

     // If we get to the end and have some items to return, then return them. 
     if (CurrentList.Count != 0) 
      yield return CurrentList; 
    } 
} 
0
string example = Encoding.ASCII.GetString(exampleArray); 
string delimiter = Encoding.ASCII.GetString(new byte[] { 0x13, 0x10 }); 
string[] result = example.Split(new string[] { delimiter}); 
string ending = Encoding.ASCII.GetString(new byte[] { 0x75, 0x3a, 0x13 }); 
bool ends = example.EndsWith(ending); 
0

Vorrei procedere con il controllo dell'elemento di array corrente e precedente. Come questo:

int[] data = ...; 

// start from second byte, to be able to touch the previous one 
int i = 1; 
while (i < data.Length) 
{ 
    if (data[i-1] == 0x13 && data[i] == 0x10) 
    { 
     // end of subarray reached 
     Console.WriteLine(); 
     i+=2; 
    } 
    else 
    { 
     // output the previous character, won't be used in the next iteration 
     Console.Write(data[i-1].ToString("X2")); 
     i++; 
    } 
} 

// process the last (or the only) byte of the array, if left 
if (i == data.Length) 
{ 
    // apparently there wasn't a delimiter in the array's last two bytes 
    Console.Write(data[i-1].ToString("X2")); 
    Console.WriteLine(" - no 0x13 010"); 
} 

Nota: l'uscita della console per il bene della manifestazione. Sostituisci con l'elaborazione dei dati effettiva.

Problemi correlati