Mar*_*vdv 1 c++ fstream iostream file bmp
我正在制作一个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++;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我在256x256的测试文件上运行它,它将打印正常,直到它达到0x36E,它给出一个错误/不会更进一步.发生这种情况是因为completeStr字符串不接收bmp文件中的所有数据.为什么无法读取bmp文件中的所有行?
您的代码存在许多问题.主要的一个(可能是你的问题的原因)是你在文本模式下打开文件.从技术上讲,这意味着如果文件包含除可打印字符和一些特定控制字符(如'\ t')之外的任何内容,则表示您有未定义的行为.实际上,在Windows下,这意味着0x0D,0x0A的序列将被转换为单个'\n',并且0x1A将被解释为文件的末尾.读取二进制数据时并不是真正想要的.您应该以二进制模式(std::ios_base::binary)打开流.
这不是一个严重的错误,但fstream
如果您只是要阅读该文件,则不应该使用.事实上,使用an
fstream应该是非常罕见的:你应该使用ifstream
或者ofstream.同样的事情也适用stringstream(但我stringstream在阅读二进制文件时没有看到任何作用).
此外(这是一个真正的错误),您正在使用结果
getline而不检查是否成功.阅读线的通常习惯是:
while ( std::getline( source, ling ) ) ...
Run Code Online (Sandbox Code Playgroud)
但是像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>()) );
Run Code Online (Sandbox Code Playgroud)