16 Bit Binärzahl in Datei ausgeben/C++ Entsprechung für C# ushort



  • Ja, damit werden die Zahlen lesbar (als String) ausgegeben.
    Du mußt die write-Funktion zur binären Ausgabe benutzen.

    PS: Der Code von @DocShoe ist also auch diesbzgl. falsch...
    PPS: @DirkB: Du meinst wohl eher

    Du hast wohl << benutzt.



  • @astro_programmer sagte in 16 Bit Binärzahl in Datei ausgeben/C++ Entsprechung für C# ushort:

    Ist das Problem, dass ich den << Operator benutze?

    Ja, siehe mein Post von oben. Link von da:
    https://en.cppreference.com/w/cpp/io/basic_ostream/write

    Zitat aus der verlinkten Seite:

    Example
    This function may be used to output object representations, i.e. binary output
    (Beispielcode ist auch da)



  • @astro_programmer

    Ich hätte schwören können, dass es einen bin Manipulator für streams gibt, aber da habe ich mich wohl getäuscht. Die Streamoperatoren funktionieren dann nicht, selbst wenn die Datei im Binary Modus geöffnet wurde. Du musst die Daten dann tatsächlich mit write schreiben, was durch die Konvertierung erschwert wird. Das hier wäre mein erster Ansatz, erfordert allerdings etwas Verständnis über die Funktionsweise von Operatorüberladung

    #include <iostream>
    #include <fstream>
    
    std::ostream& stream_binary( std::ostream& os, unsigned short val )
    {
        os.write( &val, sizeof( val );
        return os;
    }
    
    void write_sample( std::string const& filename, Sample const& sample )
    {
        ofstream ofs( filename, std::fstream::out | std::fstream::bin );
        ofs << stream_binary( sample.number )
            << stream_binary( sample.sample )
            << stream_binary( sample.max_FEE.x )
            << stream_binary( sample.max_FEE.y );
          if( !sample.Data.empty() )
          {
             os.write( &sample.Data[0], sample.Data.size() * sizeof( char ) );
          }
    }


  • @DocShoe sagte in 16 Bit Binärzahl in Datei ausgeben/C++ Entsprechung für C# ushort:

    Ich hätte schwören können, dass es einen bin Manipulator für streams gibt, aber da habe ich mich wohl getäuscht. Die Streamoperatoren funktionieren dann nicht, selbst wenn die Datei im Binary Modus geöffnet wurde.

    Das sorgt nur dafür, dass, das logische Zeilenende '\n' beim Lesen oder Schreiben in das unter dem jeweiligen Betriebssystem verwendete Zeilenende übersetzt wird (Edit: und eine Behandlung des EOF-Zeichen '\0x1A'). Siehe https://en.cppreference.com/w/cpp/io/c/FILE#Binary_and_text_modes

    Also immer binary verwenden, außer man hat Text in Zeilen.

    std::ostream& stream_binary( std::ostream& os, unsigned short val )

    Finde ich so ein bisschen schwierig, weil sich stream_binary nach was generischem anhört, bei dir aber alles in unsigned short gewandelt wird.

    ofstream ofs( filename, std::fstream::out | std::fstream::bin );

    Ein ofstream ist schon automatisch out. (und ist es nicht std::ios::binary?) Das brauchst du nicht nochmal anzugeben.



  • @wob

    Das stream_binary heisst schon absichtlich so, langfristig kann man sowas auch zu

    template<typename T>
    std::ostream stream_binary( std::ostream& os, T const& val )
    {
        os.write( &val, sizeof( val ) );
        return os;
    }
    

    umbauen.

    Nur dann braucht man Typüberprüfungen für T, und ich wollte TE hier keine SFINAE Konstrukte um die Ohren hauen.

    Zu den ostream-Flags:
    Ja, ich weiß, dass ostream Objekte standardmäßig das out-flag gesetzt haben. Ich weiß nur nicht, ob die den Parameter ergänzen, wenn man den Konstruktor mit Namen und Flags benutzt, oder ob der Parameter 1:1 übernommen wird. Daher habe ich ihn explizit gesetzt.



  • Hmmm... Von den Fehler in deinem Code mal abgesehen (mindestens: reinterpret_cast<char*> fehlt & stream_binary kann nicht einfach so eine Funktion sein - woher soll denn operator<< wissen, dass diese Fkt nun << gerufen werden soll und nicht das Ergebnis in die Datei gehen soll) - ich habe kein Problem mit write. Denn mit write sieht man ja gleich, dass hier rohe Daten geschrieben werden.



  • @wob

    Jau, ich lass das. Ohne weitere Konstrukte wird das nix, und ich wil das hier auch nicht ausufern lassen. Nur eine einfacher write Aufruf wird´s nicht werden, da die Daten als int vorliegen und als unsigned short geschrieben werden sollen.



  • So schwer ist das nicht, einen eigenen Stream-Manipulator (mit Parametern) zu schreiben - man muß dazu nur eine Klasse entwickeln, s.a. Writing Your Own Stream Manipulators.

    Einen leicht anderen Ansatz (mit eigener Binärstream-Klasse binary_ostream_wrapper) habe ich in Force stream << >> to interpret as binary gefunden.



  • @Th69

    Ne, schwierig ist das nicht. Jedenfalls nicht, wenn man sich etwas Zeit nimmt und das nicht nur im Forum ungetestet runtertippt. Aber dazu habe ich atm weder Zeit noch Lust.



  • So, jetzt habe ich das endlich ausprobiert. Nochmal vielen Dank an alle für's mit Überlegen und die hilfreichen Antworten! 🙂 Ich habe es so gemacht wie @manni66 vorgeschlagen hat und es funktioniert. Meine Funktion sieht jetzt so aus:

    void AppendToBinDataFile(Sample currentsample)
        {
            if (currentsample.ID == (int)REC_CMD_ID_DATA_UNPROC || currentsample.ID == (int)REC_CMD_ID_DATA_MAXLOC)
            {
                unsigned short SND_CMD_ID_SOP_ushort = (unsigned short)SND_CMD_ID_SOP;
                unsigned short SND_CMD_ID_EOP_ushort = (unsigned short)SND_CMD_ID_EOP;
                unsigned short number_ushort = (unsigned short)currentsample.number;
                unsigned short sample_ushort = (unsigned short)currentsample.sample;
                unsigned short maxFEEx_ushort = (unsigned short)currentsample.max_FEE.x;
                unsigned short maxFEEy_ushort = (unsigned short)currentsample.max_FEE.y;
                BinDataFile.write((char*)&SND_CMD_ID_SOP_ushort, sizeof(SND_CMD_ID_SOP_ushort));
                BinDataFile.write((char*)&number_ushort, sizeof(number_ushort));
                BinDataFile.write((char*)&sample_ushort, sizeof(sample_ushort));
                BinDataFile.write((char*)&maxFEEx_ushort, sizeof(maxFEEx_ushort));
                BinDataFile.write((char*)&maxFEEy_ushort, sizeof(maxFEEy_ushort));
               
                if (currentsample.ID == (int)REC_CMD_ID_DATA_UNPROC)
                {
                    for(std::size_t i = 0; i < currentsample.data.size(); i++)
                    {
                        unsigned short data_ushort = (unsigned short)currentsample.data[i];
                        BinDataFile.write((char*)&data_ushort, sizeof(data_ushort));
                    }
                    
                }
                BinDataFile.write((char*)&SND_CMD_ID_EOP_ushort, sizeof(SND_CMD_ID_EOP_ushort));
            }
            BinDataFile.flush();
        }
    
    

Anmelden zum Antworten