2009-03-18 3 views
0

Ich möchte OOP und STL usw. verwenden, um einen Puffer zu analysieren.Parsing-Puffer in C++ mit OOP und STL

My Buffer enthält

ABCDXXXX333$$$$YYYY 

Ich brauche ABCD XXXX 333 $$$$ YYY zu trennen und sie struct zu bewegen. Ich habe ihren Offset in einer der Regeltabelle definiert und wie viele Elemente im Puffer sind. Einige der Felder sind ebenfalls begrenzt.

  • Irgendwelche Vorschläge, welche STL-Funktionen ich verwenden kann?
  • Jeder Beispielcode funktioniert, ich werde darauf aufbauen.

Ich werde dies auf einer AIX (Unix) Box verwenden.

+0

Sind A, B, C, D ...soll etwas darstellen, oder sind es buchstäblich diese Charaktere? –

+0

Was ist "ein Puffer"? –

Antwort

0

Sie können cin.peek() verwenden, um zu sehen, ob es ein Zeichen ist, das Sie erhalten möchten (beachten Sie, dass dies nicht aus dem Stream entfernt wird). Vielleicht drei Klassen/Funktionen, um zu extrahieren, was sie mit dieser Technik machen, und zu stoppen, wenn sie einen Charakter erreichen, den sie nicht halten sollten.

1

Wahrscheinlich würde Ihre Klasse, die alle Daten enthält, eine statische Funktion haben, die das Objekt erzeugt, das Ihrer serialisierten Zeichenfolge entspricht. Wie es funktioniert, hängt von Ihren Daten ab. Sie sagen, Sie haben Offsets für Felder definiert, sagen aber auch, dass sie abgegrenzt sind. Dies stellt ein Problem dar, da beide unterschiedlich gehandhabt werden müssen.

Einfacher Fall für Ihr Beispiel:

class DataContainer 
{ 
    using namespace std; // FIXME Is this legal? 

    public: 
     DataContainer(string part1, string part2, string part3, string part4, string part5) : 
      m_part1(part1), m_part2(part2), m_part3(part3), m_part4(part4), m_part5(part5) 
     { 
     } 

     static DataContainer readFromStream(istream &stream) 
     { 
      DataContainer ret; 
      char tmp[16]; 

      stream.get(tmp, 4); 
      ret.m_part1 = string(tmp, 4); 

      stream.get(tmp, 4); 
      ret.m_part2 = string(tmp, 4); 

      stream.get(tmp, 3); 
      ret.m_part3 = string(tmp, 3); 

      stream.get(tmp, 4); 
      ret.m_part4 = string(tmp, 4); 

      stream.get(tmp, 3); 
      ret.m_part5 = string(tmp, 3); 

      return ret; 
     } 

    private: 
     DataContainer() 
     { 
     } 

     string m_part1, m_part2, m_part3, m_part4, m_part5; // Put these in an array if they belong in an array. 
}; 

Anmerkung: Ich habe alle meine Funktionen inlined. Sie sollten Ihre Funktionen wahrscheinlich in eine eigene CPP-Datei einfügen.

Verwenden Sie es wie folgt:

DataContainer dc = DataContainer::readFromStream(std::cin); 

Dieser liest die Daten aus cin (stdin) und stellt die Datenstruktur in dc.

Wenn Sie die Daten bereits gelesen haben, können Sie STL-Iteratoren (die im Grunde Zeiger auf Elemente eines Containers sind) ganz einfach verwenden. Sie können auch die klassische Indizierung verwenden, die für Ihren Fall einfacher ist. Zum Beispiel:

static DataContainer readFromBuffer(string buffer) 
{ 
    DataContainer ret; 
    ret.m_part1 = string(buffer, 0, 4); 
    ret.m_part2 = string(buffer, 4, 4); 
    ret.m_part3 = string(buffer, 8, 3); 
    ret.m_part4 = string(buffer, 11, 4); 
    ret.m_part5 = string(buffer, 15, 3); 
    return ret; 
} 
+0

Besser noch, benutze ret.m_part * .assign (buffer, start, len), was das Erstellen, Kopieren und Zerstören eines Temporären vermeidet. Und nein, der Compiler wäre nicht erlaubt, es zu optimieren, da es nicht sehen kann, wie man den Konstruktor und Operator kombiniert = – puetzk

+0

Ich bin verwirrt, ich bin neu in C++ Man kann Datacontainer-Klasse definieren und dann ret dieser Klasse zuweisen Art ? – user79292

+0

@unknown, Es tut mir leid, ich habe vergessen, "statische" in meinem Beispiel zu enthalten. Ich werde die Beispielnutzung einschließen. – strager

1

Wenn „Puffer“ wird dann von char gemacht:

string abcd = string(buffer,0,4); 
string xxxx = string(buffer,4,8); 
etc. 
0

Lesen Sie eine Zeile zu einem Zeitpunkt mit std::getline(), die die Linie in einen std::string (Ihr Puffer) stopft. Verwenden Sie dann die Methoden std::string, um die Daten gemäß Ihrem Datenformat zu analysieren. Oder verwenden Sie etwas wie Lex/Yacc, wenn Sie eine echte Grammatik beherrschen und die std :: string-Methoden schwer leserlich werden.

1

Ich würde wirklich empfehlen, eine reguläre Ausdrücke für Ihr Problem verwenden, boost::regex ist für C++ verfügbar.

Regelmäßiger Ausdruck schützt Sie vor vielen technischen Problemen, die sich in der Regel in unangenehme Sicherheitsprobleme verwandeln.