Я делаю программу на C ++, чтобы иметь возможность открывать изображение .bmp и затем помещать его в 2D-массив. Прямо сейчас у меня есть такой код:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "Image.h"using namespace std;
struct colour{
int red;
int green;
int blue;
};
Image::Image(string location){
fstream stream;
string tempStr;
stringstream strstr;
stream.open(location);
string completeStr;
while(!stream.eof()){
getline(stream, tempStr);
completeStr.append(tempStr);
}
cout << endl << completeStr;
Image::length = completeStr[0x13]*256 + completeStr[0x12];
Image::width = completeStr[0x17]*256 + completeStr[0x16];
cout << Image::length;
cout << Image::width;
cout << completeStr.length();
int hexInt;
int x = 0x36;
while(x < completeStr.length()){
strstr << noskipws << completeStr[x];
cout << x << ": ";
hexInt = strstr.get();
cout << hex << hexInt << " ";
if((x + 1)%3 == 0){
cout << endl;
}
x++;
}
}
Теперь, если я запущу это в моем тестовом файле 256×256, он будет печататься нормально, пока не достигнет 0x36E, где выдает ошибку / не идет дальше. Это происходит потому, что completeStr Строка не получает все данные, которые находятся в файле BMP. Почему не может прочитать все строки в файле bmp?
Есть ряд проблем с вашим кодом. Основной
один (и, вероятно, причина вашей проблемы) заключается в том, что вы
Открытие файла в текстовом режиме. Технически это означает, что если
файл содержит что угодно, кроме печатных символов и нескольких
конкретные управляющие символы (например, \ t), у вас есть неопределенные
поведение. На практике под Windows это означает, что последовательности
0x0D, 0x0A будет преобразован в один '\n'
и что
0x1A будет интерпретироваться как конец файла. На самом деле, нет
что нужно при чтении двоичных данных. Вы должны открыть
поток в двоичном режиме (std::ios_base::binary
).
Не серьезная ошибка, но вы не должны использовать fstream
если вы только собираетесь прочитать файл. На самом деле, используя
fstream
должно быть очень редко: вы должны использовать либо ifstream
или же ofstream
, То же самое относится и к stringstream
(но
Я не вижу никакой роли для stringstream
при чтении двоичного файла
файл).
Кроме того (и это настоящая ошибка), вы используете результаты
getline
без проверки, успешно ли это. Обычный
идиома для чтения строк будет:
while ( std::getline( source, ling ) ) ...
Но, как stringstream
, вы не хочу использовать getline
на
двоичный поток; это удалит все '\n'
(который имеет
уже был сопоставлен с CRLF).
Если вы хотите, чтобы все данные в памяти, самое простое решение
что-то вроде:
std::ifstream source( location.c_str(), std::ios_base::binary );
if ( !source.is_open() ) {
// error handling...
}
std::vector<char> image( (std::istreambuf_iterator<char>( source ) ),
(std::istreambuf_iterator<char>()) );
std::getline
читает в строке текста.
Это не полезно для двоичного файла.
Откройте файл в двоичном режиме и используйте неотформатированные операции ввода (например, read
).