2016-07-27 3 views
2

Я пытаюсь прочитать данные из двоичного файла в std :: string. Вот что я пробовал вначале.Чтение двоичных данных в 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 ; 
} 

И компилятор дал ошибку:

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

Насколько я понимаю, c_str() возвращает константный указатель, который не может быть использован в методе чтения, поэтому я изменил мой подход немного (что вы можете увидеть ниже). Есть лучший способ сделать это ?

#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 ; 
} 

пс: простите меня, если я не мог заставить себя ясно, что это мой первый раз здесь :)

+0

Я хотел бы использовать 'станд :: вектор ' или 'станд :: вектор ' вместо из 'std :: string' – Slava

+0

Я никогда не мог понять, почему люди используют' std :: string' для двоичных данных. Имейте в виду, что «value_type» этого контейнера является 'char', что может привести к проблемам, связанным с расширением знака (например, подумайте о том, каким будет результат' my_str [3] == 0x95'). Вы можете использовать 'std :: vector '. –

ответ

3

В C++ 11, так, чтобы получить не- const указатель на данные струны является:

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

C++ 17 будет ввести не- constdata() для этого, а также:

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

Эти причуды действительно делают C++ отличным. Удобный не-const метод для получения внутреннего буфера строки будет добавлен через 35 лет. –

+0

Чтобы убедиться, что размер my_str перед вызовом метода чтения должен быть больше или равен 5, правильно? @Barry –

+0

@baris_esmer Конечно. Все обычные оговорки применяются. – Barry

1

другим способом, используя стандартные алгоритмы:

#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 разработан специально для работы со строками и со строками в стиле С, так что этот факт будет работать против вас в этой ситуации. Например, ваш код:

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

что с этим связано? Вы читаете двоичные данные, и кто гарантирует, что там не будет байта '\ 0'? Вы можете исправить это:

my_str = string(buffer,5); 

, но это показывает точку - std::string как буфер не является хорошим выбором. Так что лучше использовать std::vector<char> или даже лучше std::vector<uint8_t> который имеет метод data() но не неявное преобразование из с-строки, выход в std::ostream и т.д.

Смежные вопросы