2016-07-27 25 views
2

Ich versuche, Daten aus einer Binärdatei zu einem Std :: String zu lesen. Hier ist was ich zuerst versucht habe.Lesen von Binärdaten in std :: string C++

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

int main(int argc, char const *argv[]) 
{ 
    fstream file("output.bin" , ios::out | ios::binary | ios::in); 
    string my_str(5, '\0'); 
    file.read(my_str.c_str(), 5); 
    cout << "String = " << my_str<< endl ; 
} 

Und der Compiler gab den Fehler:

error: invalid conversion from ‘const char*’ to ‘std::basic_istream<char>::char_type* {aka char*}’ [-fpermissive] 
    file.read(my_str.c_str(), 5); 

Soweit ich verstehe, c_str() ein const Zeiger zurückgibt, die nicht in Leseverfahren verwendet werden kann, also habe ich mein Ansatz ein wenig (was Sie unten sehen können). Gibt es einen besseren Weg, dies zu tun?

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

int main(int argc, char const *argv[]) 
{ 
    fstream file("output.bin" , ios::out | ios::binary | ios::in); 
    string my_str(5, '\0'); 
    char buffer[6]; 
    file.read(buffer, 5); 
    buffer[5] = '\0'; 
    my_str = string(buffer); 

    cout << "String = " << my_str<< endl ; 
} 

ps: mir verzeihen, wenn ich mich nicht deutlich machen konnte, dies ist mein erstes Mal hier :)

+0

ich würde 'std :: vector ' oder 'std :: vector ' statt von 'std :: string' – Slava

+0

Ich konnte nie verstehen, warum Leute' std :: string' für binäre Daten benutzen. Denken Sie daran, dass der "value_type" dieses Containers "char" ist, was zu Problemen in Bezug auf die Zeichenerweiterung führen kann (denken Sie zum Beispiel daran, was das Ergebnis von "my_str [3] == 0x95" sein wird). Sie könnten 'std :: vector ' verwenden. –

Antwort

3

In C++ 11, die Art und Weise einen nicht const Zeiger auf die Zeichenfolge der Daten zu erhalten ist:

file.read(&my_str[0], 5); 

++ 17 C als auch nicht-constdata() dafür einführen:

file.read(my_str.data(), 5); 
+2

Diese Macken machen C++ wirklich großartig. Eine bequeme nicht-konstante Methode, um den internen String-Puffer zu erhalten, wird 35 Jahre später hinzugefügt. –

+0

Nur um sicher zu sein, sollte die Größe von my_str vor dem Aufruf der Lese-Methode größer oder gleich 5 sein, oder? @Barry –

+0

@baris_esmer Natürlich. Alle üblichen Vorbehalte gelten. – Barry

1

eine andere Art und Weise unter Verwendung von Standardalgorithmen:

#include <iostream> 
#include <string> 
#include <fstream> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

int main(int argc, char const *argv[]) 
{ 
    fstream file("output.bin" , ios::out | ios::binary | ios::in); 

    auto my_str = string(); 

    copy_n(istream_iterator<char>(file), 
      5, 
      std::back_inserter(my_str)); 

    cout << "String = " << my_str<< endl ; 
} 
0

std::string ist speziell mit Streichern zu arbeiten entworfen und mit C-Strings als auch, so wird diese Tatsache gegen Sie in dieser Situation arbeiten. Zum Beispiel Ihr Code:

char buffer[6]; 
file.read(buffer, 5); 
buffer[5] = '\0'; 
my_str = string(buffer); 

was ist los damit? Sie lesen Binärdaten und wer garantiert, dass dort kein '\ 0' Byte steht? Sie können das Problem beheben, indem:

my_str = string(buffer,5); 

aber dies zeigt den Punkt - std::string als Puffer keine gute Wahl ist. Also besser std::vector<char> oder noch besser std::vector<uint8_t> verwenden, die Methode hat data() aber nicht implizit konvertieren von c-string, Ausgabe std::ostream usw.