2017-02-23 1 views
1

den folgenden Code Gegeben:Ist der Standardmodus der Ofstream-Implementierung definiert?

std::ofstream stream("somefile"); 

if (!stream) 
{ 
    return 1; 
} 

Wenn .WRITE Aufrufen (....) undSTDC++ und libC++ der Strom ist im Binärmodus (std::ios::binary) verwendet wird.

jedoch, wenn mit MSVC(2015/2017RC1) es im Textmodus oder etwas seltsam, weil das die resultierende Datei größer zu sein scheint als das, was tatsächlich geschrieben.

Aber wenn ich explizit den Modus setzen std::ios::binary MSVC verhält sich ähnlich wie die Implementierungen anderer Standard-Bibliotheken, die bereits erwähnt.


Beispielcode:

#include <vector> 
#include <cstdio> 
#include <fstream> 

std::size_t fsz(const char* filename) { 
    std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary); 
    return static_cast<std::size_t>(in.tellg()); 
} 

int main() { 
    std::ofstream stream("filename"); 

    if (!stream) 
     return 1; 

    std::vector<unsigned long long int> v = {0x6F1DA2C6AC0E0EA6, 0x42928C47B18C31A2, 0x95E20A7699DC156A, 0x19F9C94F27FFDBD0}; 

    stream.write(reinterpret_cast<const char*>(v.data()),v.size() * sizeof(unsigned long long int)); 

    stream.close(); 

    printf("expect: %d\n", v.size() * sizeof(unsigned long long int)); 
    printf("file size: %d\n", fsz("filename")); 

    return 0; 
} 

Ausgang für den obigen Code, wenn sie mit msvc auszuführen:

expect: 32 
file size: 33 

Ausgang für den obigen Code, wenn sie mit Libc laufen ++, STDC++:

expect: 32 
file size: 32 

Der Unterschied kann m erhalten Je größer, hängt davon ab, wie viele Daten geschrieben werden und wie die Dateninhalte aussehen.

am Ende ist meine Frage immer noch die gleiche, ist es nicht definiert oder unspezifiziertes Verhalten?


den obigen Vektor der folgenden Veränderung macht das Beispiel noch deutlicher als auf was los ist.

std::vector<unsigned long long int> v = {0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A}; 
+0

Bitte beschreiben Sie _exactly_, was Sie sehen. Größer um wie viel? Was enthält die Datei? Wo ist dein 'write()' Anruf? Präsentiere ein [MCVE]. –

+0

@LightnessRacesinOrbit Ich habe ein Beispiel hinzugefügt. –

Antwort

3

Der Standardmodus durch den Strom Konstruktor verwendet ios_base::out ist. Da es kein explizites text Modus-Flag gibt, bedeutet dies, dass der Stream im Textmodus geöffnet wird. Der Textmodus wirkt sich nur auf Windows-Systeme aus und konvertiert \n Zeichen in CR/LF-Paare. Auf POSIX-Systemen hat dies keine Auswirkungen, und Text- und Binärmodi sind auf diesen Systemen gleichbedeutend.

+0

0x0A Bytes werden in 0x0D0A konvertiert, also im 3. Element des Vektors wird das 0x0A Byte unter Windows 'verdoppelt'. –

+0

Also @Torrie wie bist du zu folgendem Schluss gekommen? _ "Beim Aufruf von .write (....) und unter Verwendung von stdC++ und libC++ befindet sich der Stream im Binärmodus (' std :: ios :: binary'). "_ Das scheint nicht wahr zu sein. –

3

Wenn ich Ihren Code auf Windows laufen mit g++ und libstdc++, erhalte ich das folgende Ergebnis:

expect: 32 
file size: 33 

Das Problem ist also nicht spezifisch Compiler, sondern OS spezifisch.

Während C++ ein einzelnes Zeichen \n verwendet, um eine Zeile darzustellen, die in einer Zeichenfolge endet, verwendet Windows zwei Bytes 0x0D und 0x0A für eine Zeile, die in einer Datei endet. Das bedeutet, wenn Sie eine Zeichenfolge in eine Datei im Textmodus schreiben, werden alle Vorkommen des einzelnen Zeichens \n mit diesen zwei Bytes geschrieben. Deshalb erhalten Sie zusätzliche Bytes in der Dateigröße Ihrer Beispiele.

+0

''\ n'' in einem Zeichen oder einem String-Literal endet eine Zeile in ** jedem ** C- und C++ - Programm. In einer ** Datei ** unter Windows wird das Ende einer Zeile durch zwei Bytes repräsentiert, mit den Werten '0x0D' und '0x0A'. Zufällig stimmen diese Werte mit den Werten überein, die Compiler verwenden, wenn sie in einer ** Quelldatei ** "\ r" und "\ n" sehen. Es gibt keine ** erforderliche ** Verbindung zwischen "" und "\ n" und einem bestimmten Wert in kompiliertem Code oder in einer Textdatei. –

+0

@PeteBecker Danke, ich habe meine Antwort aktualisiert. – pschill

+0

Gut gemacht! (Füllung ignorieren) –

Verwandte Themen