Problem mit "reverse"



  • Isomorphismus schrieb:

    bei meinem char array bekomme ich das, und das ist das, das ich im endeffekt benötige

    WAS benötigst Du im Endeffekt ?
    Dass intern mit Zeichen gearbeitet wird ?
    und wofür ?
    Was ist genau Dein Problem mit Jaxoms Lösung ?

    Gruß,

    Simon2.



  • wie casten?
    ich poste jetzt das, was ich eigentlich brauche:

    ich habe ein float array xNeData, in dem Werte drinnen stehen, und die möchte ich binär in ein File schreiben, wobei ich aber das byteordering umdrehen soll (wegen big und little endian). der code sieht so aus:

    for(i;i<99;i++)
    
    	{
    	 char *buffer= reinterpret_cast<char*>(&xNeData[i]); 
    	 reverse(buffer,buffer+4); //hier liegt das Problem
    	 vtkWriter.write(buffer,4);
    	}
    

    und die leseroutine, mit der ich andere files dieser art auslese, sieht folgendermaßen aus:

    while(!tReader.eof()) //!tReader.eof()
    			{tReader.read(data, sz); 
    			for(size_t i = 0; i != sz; ++i) dataReversed[sz-i-1] = data[i];
    
    			DataType *p_wert = reinterpret_cast<DataType*>(dataReversed);
    
    			tData[i]=*p_wert;
    			i++;
    			} //tData gespeichert zur Weiterverarbeitung
    

    Das problem ist jetzt, dass ich, wenn ich die werte auslese, einfach nicht die richtigen werte in meinem file stehen habe (die ausleseroutine ist aber an anderen files dieser art getestet und funktioniert). also muss ich irgendetwas beim schreiben falsch machen..

    lg,
    Iso



  • Isomorphismus schrieb:

    ...die möchte ich binär in ein File schreiben...

    Wozu soll das gut sein ? Das Format ist hochgradig maschinenabhängig (wie Du z.B. bereits am endian-Problem festgestellt hast, aber hinter dieser Tür stecken noch mehr und häßlichere Monster) ....
    Ich könnte mir höchstens vorstellen, dass Du eine von außen vorgegebene Schnittstelle bedienen musst - aber da würde ich nicht mit der Binärdarstellung Deiner Plattform rumspielen, sondern die Schnittstelle klar definieren und umsetzen (welcher Wert soll im ersten Byte stehen, welcher im zweiten, ....).

    Sorry, wen das jetzt ein wenig ruppig klingt, aber ich bin immer wieder überrascht, wie oft Leute unbedingt "im Binärformat (des gerade aktuellen Compilers) schreiben" wollen (bzw. zu müssen meinen) ... in 95% der Fälle erweist sich das diese Entscheidung als vorschnell und schmerzhaft.

    Was spricht wirklich gegen einfaches

    ofstream out("MyFile.txt");
    float f = 1.23;
    out << f;
    

    ??

    Das kannst Du überall (wo derselbe Zeichensatz verstanden wird) ebenso simpel und sicher wieder einlesen mit

    ifstream in("MyFile.txt");
    float f;
    in >> f;
    

    ganz unabhängig vom Maschinenformat, Compiler(-einstellungen), ...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Isomorphismus schrieb:

    ...die möchte ich binär in ein File schreiben...

    Wozu soll das gut sein ? Das Format ist hochgradig maschinenabhängig (wie Du z.B. bereits am endian-Problem festgestellt hast, aber hinter dieser Tür stecken noch mehr und häßlichere Monster) ....
    Ich könnte mir höchstens vorstellen, dass Du eine von außen vorgegebene Schnittstelle bedienen musst - aber da würde ich nicht mit der Binärdarstellung Deiner Plattform rumspielen, sondern die Schnittstelle klar definieren und umsetzen (welcher Wert soll im ersten Byte stehen, welcher im zweiten, ....).

    Sorry, wen das jetzt ein wenig ruppig klingt, aber ich bin immer wieder überrascht, wie oft Leute unbedingt "im Binärformat (des gerade aktuellen Compilers) schreiben" wollen (bzw. zu müssen meinen) ... in 95% der Fälle erweist sich das diese Entscheidung als vorschnell und schmerzhaft.

    Was spricht wirklich gegen einfaches

    ofstream out("MyFile.txt");
    float f = 1.23;
    out << f;
    

    ??

    Das kannst Du überall (wo derselbe Zeichensatz verstanden wird) ebenso simpel und sicher wieder einlesen mit

    ifstream in("MyFile.txt");
    float f;
    in >> f;
    

    ganz unabhängig vom Maschinenformat, Compiler(-einstellungen), ...

    Gruß,

    Simon2.

    Naja, es gibt auch durchaus Fälle, wo man das braucht.
    Als recht einfaches Beispiel kann man hier. z.B. wav- oder bmp-Dateien nennen, da werden die Samples Little-Endian abgelegt. Oder auch aif, das ist Big-Endian, (glaube ich). Nur wenn man ein funktionales Interface für den Zugriff auf solche Formate anbietet, muss man das halt berücksichtigen...

    PS: Nichts desto trotz stimme ich Dir zu: Man sollte es lassen, wenns nicht nötig ist.



  • Tachyon schrieb:

    ...
    Naja, es gibt auch durchaus Fälle, wo man das braucht.
    Als recht einfaches Beispiel kann man hier. z.B. wav- oder bmp-Dateien nennen, da werden die Samples Little-Endian abgelegt. Oder auch aif, das ist Big-Endian, (glaube ich)....

    Genau das meinte ich mit:

    Simon2 schrieb:

    ...
    Ich könnte mir höchstens vorstellen, dass Du eine von außen vorgegebene Schnittstelle bedienen musst - aber da würde ich nicht mit der Binärdarstellung Deiner Plattform rumspielen, sondern die Schnittstelle klar definieren und umsetzen (welcher Wert soll im ersten Byte stehen, welcher im zweiten, ....)....

    Tachyon schrieb:

    ...
    PS: Nichts desto trotz stimme ich Dir zu: Man sollte es lassen, wenns nicht nötig ist.

    Genau ! Und ich würde noch erweitern zu: Es ist nur sehr selten wirklich nötig (und zwar deutlich seltener als Einsteiger das glauben ... bis hin zu: Wenn ein Einsteiger das glaubt, stimmt's nicht) 😉

    Gruß,

    Simon2.



  • Bei eigenen Interfaces eigentlich nur dann, wenn man sehr schnell sehr große Mengen an numerischen Daten durch die Mangel drehen muss und die String->Wert Konvertierung zu viel Zeit schluckt.
    Oder vielleicht noch, wenn große Mengen an Daten gespeichert werden müssen, und ein binäres Format debei deutliche Ersparnisse bedeutet.



  • Tachyon schrieb:

    ...sehr schnell sehr große Mengen ...

    ... und das machen Anfänger so gut wie nie (glauben es aber überdurchschnittlich oft ... "Ey ! Das sind 500 Zeilen !! Und Performance ist sauwichtig, Mann !!") 😃

    Gruß,

    Simon2.



  • tja, liebe leute, das soll ein .vtk File werden,welches mit spezieller software visualiert werden soll, und diese software braucht die binärdarstellung. ich hätte auch lieber die konkreten werte ins file geschrieben.



  • Isomorphismus schrieb:

    tja, liebe leute, das soll ein .vtk File werden,welches mit spezieller software visualiert werden soll, und diese software braucht die binärdarstellung. ich hätte auch lieber die konkreten werte ins file geschrieben.

    Tja Leut,
    also: extern vorgegebene Schnittstelle (was übrigens einfacher gewesen wäre, wenn Du's gleich geschrieben hättest).
    Aaaaber: Das bedeutet noch lange nicht, dass sie die Binärformate bestimmter Datentypen Deines konkreten Compilers benutzen würde. ... und ich würde auch nicht versuchen, dass zu verquicken, sondern eine klare Abbildung schaffen von den internen Datenformaten MEINES Programms auf das "vtk-Datenformat".
    Bisweilen kann das einfach sein (wie die Abbildung eines chars auf ein vtkZeichen, wenn derselbe Zeichensatz und dieselbe interne Darstellung genommen werden), kann aber auch bedeuten, dass komplizierte Strukturen transformieren musst (wenn z.B. ein C++-Objekt in ein xml-Objekt überführt werden muß).

    Für Quickreader: Beware of reinterpret_cast !!!

    Gruß,

    Simon2.



  • ??
    Also ich hab gar nichts verstanden, simon, was soll ich machen? (bzw worüber soll ich mich schlau machen?)

    lg,
    Iso



  • Isomorphismus schrieb:

    ??
    Also ich hab gar nichts verstanden, simon, was soll ich machen? (bzw worüber soll ich mich schlau machen?)

    lg,
    Iso

    Naja, ich meine halt sowas:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <iterator>
    #include <algorithm>
    using namespace std;
    
    struct MyData {
       MyData(float af, string const& as, char ac) : f(af), s(as), c(ac) {}
       float f;
       string s;
       char c;
    };
    
    string int4digits2BCD(int t) {
       char buf[2];
       t %= 10000;
       buf[0] = (0x10*(t/1000)%10) + (t/100)%10;
       buf[1] = (0x10*(t/10)%10) + t%10;
       return string(buf, 2);
    }
    
    void toVTKFormat(MyData const& m, vector<char>& v) {
       float absolut = fabs(m.f);
       // 1 Byte: Vorzeichen von f; positiv => '$' ; negativ => '%'
       v.push_back(m.f == absolut ? '$' : '%' );
    
       // 4 Bytes: f als <abcd>.<efgh> bcd-codiert Bigendian
       int vorkomma = absolut;
       string vorkommaBCD(int4digits2BCD(vorkomma));
       copy(vorkommaBCD.begin(), vorkommaBCD.end(), back_inserter(v));
    
       int nachkomma = (absolut * 10000) - (vorkomma * 10000);
       string nachkommaBCD(int4digits2BCD(nachkomma));
       copy(nachkommaBCD.begin(), nachkommaBCD.end(), back_inserter(v));
    
       // 1 Byte Filler
       v.push_back('f');
    
       // n Byte: s
       copy(m.s.begin(), m.s.end(), back_inserter(v));
    
       // 1 Byte: c
       v.push_back(m.c);
    }
    
    int main() {
       cout << "hello world\n";
       MyData m(-1.23f, "Simon2", 'x');
       vector<char> VTKData;
    
       toVTKFormat(m, VTKData);
    
       copy(VTKData.begin(), VTKData.end(), ostream_iterator<char>(cout, " "));
    
       return 0;
    }
    

    Da fehlen natürlich noch eine Menge Plausiprüfungen und letztlich würde ich das auch über einen operator<<(ostream&, ...) machen, aber der Ansatz wird hoffentlich klar:
    toVTKFormat() übernimmt die Formatwandlung auf Byteebene.
    Es konvertiert ein MyData-Objekt (mit dem ich gut und bequem in meinem Code arbeiten kann) in ein vordefiniertes Format.

    Gruß,

    Simon2.


Anmelden zum Antworten