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 inline

    Nachteil:
    - 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


Anmelden zum Antworten