String 'umwandeln'
-
Hallo
Ich habe einen String, der eine Binärzahl enthält.
Diesen String muss ich jetzt irgendwie in einzelne Bytes umwandeln.
Bsp:char* test = "1111111110101010";
wird zu
BYTE soundso[]={0xFF, 0xAA};
Aber heute ist nicht so mein Tag... Ich scheitere schon am Trennen des Strings...
Vielleicht springt ja irgendjemand eine Lösung ins Auge.
Danke schon mal - Andiri
-
std::string benutzen, dann mit substr immer 8 zeichen rauskopieren, zeichenweise durchlaufen und den Wert ausrechnenen...
Mfg, smasher1985
-
Hallo,
ich habe mal eine Klasse mit minimaler implementierung zusammengebastelt.
Die Klasse funktnioniert zwar, kann aber noch um einige Funktionen erweitert
werden...#include <iostream> using namespace std; class ByteArray { public: explicit ByteArray(const char* szStringOfBits); ~ByteArray(); size_t Size() const { return m_length; } int operator [] (size_t index) const; protected: void Parse(const char* szBits); private: unsigned char* m_array; size_t m_length; }; ByteArray::ByteArray(const char* szStringOfBits) : m_array(0), m_length(0) { Parse( szStringOfBits ); } ByteArray::~ByteArray() { delete[]m_array; } inline int ByteArray::operator [](size_t index) const { return index > m_length ? 0 : static_cast<int>( m_array[index] ); } void ByteArray::Parse(const char* szBits) { size_t len = strlen( szBits ); if ( len % 8 ) return; m_length = len / 8; m_array = new unsigned char[m_length]; memset( m_array, 0, m_length ); const char* bit = szBits; unsigned char* byte = m_array; size_t bitpos = 0; while ( *bit ) { char ch = *bit++; bitpos = (bit - 1 - szBits) % 8; if ( ch == '1' ) *byte |= 128 >> bitpos; if ( bitpos == 7 ) ++byte; } } int _tmain(int argc, _TCHAR* argv[]) { ByteArray bytes( "1111111110000000" ); for ( size_t i = 0; i < bytes.Size(); ++i ) cout << bytes[i] << endl; return 0; }
Dies ist zwar eine Lösung, aber wie gesagt, noch nicht perfekt.
Gruss
EarlyBird
-
mal ne blöde Frage. Was macht denn das Schlüsselwort explicit? Das ist mir ja noch nie begegnet
Mfg, smasher1985
-
explicit verwendet man bei Konstruktoren die nur einen Parameter haben,
damit bei der Übergabe keine implicite Umwandlung des Objekts zugelassen
wird.siehe dazu auch in der MSDN
This keyword is a declaration specifier that can only be applied to in-class constructor declarations. An explicit constructor cannot take part in implicit conversions. It can only be used to explicitly construct an object.
-
ahja, danke schö4n...wieder ein quäntchen schlauer
Mfg, smasher1985
-
Vielen Dank schon mal.
Hab aber auch noch eine Frage.inline int ByteArray::operator [](size_t index) const { index > m_length ? return 0 : return static_cast<int>( m_array[index] ); }
Es geht um dieses Stück Code.
Was ist denn die Funktion von Inline Int? So etwas ist mir noch nie begegnet.
Außerdem muckt der Compiler hier rum:
error C2059: syntax error : 'return'Wär nett, wenn du darauf etwas eingehen würdest.
-
Hi,
hat sich beim optimieren ein fehler eingeschlichen...
Der Abschnitt muss so aussehen:inline int ByteArray::operator [](size_t index) const { return index > m_length ? 0 : static_cast<int>( m_array[index] ); }
Die Funktion überlädt den [] operator um die erzeugten Bytes per Index
abzurifen.
Man hätte auch einen Getter schreiben können ala GetAt(0).inline bedeutet das der Compiler versuchen soll, eine Kopie der Funktion
an der Quellltextstelle zu setzen, also etwa in der Art wie ein #define.
Das macht den Code schneller, da kein Funktionssprung gemacht wird.
-
Danke für die Erklärung.
Aber wird dadurch nicht die Datei um ein vielfaches größer, wenn die Funktion immer kopiert wird? Naja irgend einen Haken gibts immer.
Gruß - Andiri.
-
Hi,
ich denke nicht, das dein programm dadurch größer wird.
Angenommen ich habe folgende Struktur:
struct Point { int x; int y; };
und habe in meinen Quelltext jedesmmal dieses:
if ( point.x == 0 || point.x > 400 ) { // do something }
oder ich habe dieses:
#define IS_INRANGE(x) if ( (x).x == 0 || (x).x > 400 ) return true; IS_INRANGE(point) { // do something } // Compiler macht daraus if ( if ( (point).x == 0 || (point).x > 400 ) return true; ) { // do something }
oder du hast besagte inline funktion:
struct Point { int x; int y; inline bool IsInRange() const { return x == 0 || x > 400; } } if ( point.IsInRange() ) { // do something } // Compiler macht daraus if ( point.x == 0 || point.x > 400 ) { // do something }
Der Code bleibt also derselbe.
Vorteile:
- x und y brauchen nicht public zu sein bei einer Klasse
- die member daten bleiben gekapselt
- der source scheint lesbarer (IMHO)
- wenn aus 400 mal 500 werden soll, änderung nur an einer stelle
- usw.Besonderer Vorteil:
- trotz funktion kein funktionssprung weil inlineNachteil:
- man kann nicht genau sagen, ob der compiler die funktion wirklich 'inlined'
allerdings kann man bei funktionen dieser art (nur eine zeile code und kein
funktionsaufruf innerhalb der zeile) fast 99.99% sagen, das es auch inline wird.Ich hoffe das ist nun etwas klarer geworden.
Gruss
EarlyBird