ints to Hex-String mit zweistelligen Zahlen



  • Ich möchte ints in einen Hexstring konvertieren, hier ist mein Ansatz:

    #include <string>
    #include <sstream>
    #include <iomanip>
    
    	std::string convertToHex(const std::vector<int>& vec) {
    		std::stringstream ss;
    		ss << std::hex;// << std::setw(2) << std::setfill('0');
    
    		for (size_t i = 0; i < vec.size(); ++i) {
    			ss << vec[i]<< " ";  
    		}
    
    		return ss.str();
    	}
    
    int main() {
    
    	std::vector<int> ints;
    	ints.push_back(0);
    	ints.push_back(7);
    	ints.push_back(193);
    	ints.push_back(255);
    	ints.push_back(3);
    	ints.push_back(10);
    	ints.push_back(13);
    	ints.push_back(127);
    	ints.push_back(5);
    	ints.push_back(220);
    	cout<<convertToHex(ints)<<endl;
    	cin.get();
    }
    }
    

    Problem: Ich erhalte folgende Ausgabe:

    0 7 c1 ff 3 a d 7f 5 dc
    

    Kommentiere ich meinen Versuch ein (siehe Quelltext oben) erhalte ich immerhin:

    00 7 c1 ff 3 a d 7f 5 dc
    

    Ich will aber

    00 07 c1 ff 03 0a 0d 7f 05 dc
    

    haben 😕



  • setw und setfill wirken sich nur auf die nächste ausgegeben Zahl aus. Das muss also in die Schleife.





  • Wo ist das definiert, also dass sich die Formatflags nur auf die nächste Ausgabe beziehen.

    Ich lese im Moment das Buch "Standard c++ IOStreams and Locales" von Angelika Langer und Klaus Kreft, aber da wurde das auch (noch) nicht gesagt.

    In meinen Augen macht es Ausgaben einiges schwieriger.



  • *seufz* 😞 Ab und zu stell ich mich echt dämlich an



  • @Skymosho:
    Das ist auch dämlich, dass das nur für die nächste Ausgabe geht.
    Deswegen verwende ich die Manipulatoren mit Flags gar nicht erst.
    ios_base hat so schöne Funktionen width(), fill(), etc., die genau das abdecken.

    @KeinHexenmeister:
    Iteratoren anstatt Containerübergabe macht deine Funktion auch generischer.

    Edit: Ich finde das Stream-System generell ein bissche seltsam.
    Die Konsole ist aufgeteilt in ostream und istream anstatt ein iostream-Objekt, Streams sind von Anfang an für strings gedacht (ich verwende gerne Streams (in meinen Fall reine Klassen mit << und/oder >>-Operator) für alles mögliche, Zeichnen von Objekten auf Bildschirmen/Bildern, Senden von Nachrichten an andere Computer, Message-Handling, etc., komplett generische Streams wären da manchmal schön, aber vielleicht bin ich auch der einzige, der das so sieht), etc.
    Wenigsten das filename.c_str() ist nun behoben. 🙄
    Ach, und wo wir gerade bei std::strings sind: Was sollen die dreitausend find Funktionen in der String-Klasse? Warum nicht wie bei den Containern, als Algorithmus in algorithm?



  • Nathan schrieb:

    @Skymosho:
    Das ist auch dämlich, dass das nur für die nächste Ausgabe geht.
    Deswegen verwende ich die Manipulatoren mit Flags gar nicht erst.
    ios_base hat so schöne Funktionen width(), fill(), etc., die genau das abdecken.

    D.h. die Flags gelten nur für die nächste Ausgabe, die äquivalenten Funktiosnaufrufe jedoch immer? (Bis zur nächsten änderung natürlich nur) ???



  • Ja, ich denke schon, sofern sich in letzter Zeit nichts geändert hat.



  • Vorschlag:

    #include <iostream>
    #include <vector>
    
    template< typename C >
    struct convertToHex_type
    {
        convertToHex_type( const C& c ) : c_(c) {}
        friend std::ostream& operator<<( std::ostream& out, convertToHex_type x )
        {
            const char old_fill = out.fill('0');
            out << std::hex;
            for( auto i = begin(x.c_); i != end(x.c_); ++i )
            {
                out.width( 2 );
                out << *i << " ";
            }
            out.fill( old_fill );
            return out;
        }
    private:
        const C& c_;
    };
    
    template< typename C > // --    factory function für convertToHex_type< C >
    convertToHex_type< C > convertToHex( const C& vec ) 
    {
        return convertToHex_type< C >( vec );
    }
    
    int main()
    {
        using namespace std;
    
        std::vector<int> ints;
        ints.push_back(0);
        ints.push_back(7);
        ints.push_back(193);
        ints.push_back(255);
        ints.push_back(3);
        ints.push_back(10);
        ints.push_back(13);
        ints.push_back(127);
        ints.push_back(5);
        ints.push_back(220);
        cout<<convertToHex(ints)<<endl;
    }
    

    ohne string und ohne stringstream und ohne überflüssiges Kopieren.



  • Ich würd' das Ganze natürlich nicht convertToHex nennen. Denn schließlich wird hier nichts konvertiert. Eher etwas in die Richtung wie printAsHexadecimal oder so.


Anmelden zum Antworten