ifstream::read 不读取 unsigned char,即使 reinterpret_cast
ifstream::read not reading unsigned char, even with reinterpret_cast
我正在尝试让我的代码读取 PPM 图像 (P3),但它没有正常工作。这个想法是获取 3 个无符号字符并将它们存储在 RGB 中。但目前它只会导致取第一个字符而忽略其余字符。
Image Image::readImg(std::string const &filename) {
std::ifstream ifs;
ifs.open(filename.c_str(), std::ios::binary);
Image _in;
try {
if (ifs.fail()) {
throw("Can't open input file");
}
std::string header;
int w, h, max;
ifs >> header;
if (strcmp(header.c_str(), "P3") != 0) throw("Can't read input file");
ifs >> w >> h >> max;
_in.init(w, h);
ifs.ignore(256, '\n');
unsigned char pix[3];
for (int i = 0; i < h; ++i){
for (int j = 0; j < w; ++j){
ifs.read(reinterpret_cast<char *>(pix), 3);
_in.pixels[i][j].R = pix[0];
_in.pixels[i][j].G = pix[1];
_in.pixels[i][j].B = pix[2];
}
}
std::cout << "|" << _in.pixels[0][0].R << " " << _in.pixels[0][0].G << " " << _in.pixels[0][0].B << "|";
ifs.close();
}
catch (const char *err) {
fprintf(stderr, "%s\n", err);
ifs.close();
}
return _in;
}
请注意,std::cout 应该在我的场景中输出 |186 0 255|,但我却得到了 |1 8 6|。
编辑: 文件 (original.ppm) 在 Notepad++ 中打开时,看起来像这样 (UNIX / UTF-8):
P3
1024 768
255
186 0 255 186 0 255 186 0 255 186 0 255 186 0 255 186 0 255 186 1 255
186 1 254 186 1 254 185 2 254 185 2 254 185 1 254 185 2 253 185 3 253
185 2 252 185 3 252 185 3 252 185 3 252 185 3 251 184 4 251 184 4 251
184 4 251 184 4 251 184 5 250 184 5 250 183 5 250 183 6 249 183 6 249
183 6 249 183 6 248 183 7 249 183 7 249 183 7 248 183 7 247 183 8 247
182 7 247 182 8 246 183 9 247 183 9 246 183 9 246 182 9 246 181 9 246
182 9 246 181 10 245 182 10 245 181 10 244 181 10 245 181 11 244 181 11 244
...
结果应该是:
_in.pixels[0][0].R = 186
_in.pixels[0][0].G = 0
_in.pixels[0][0].B = 255
并继续收集文件中所有像素的RGB。
默认情况下,在流中使用 >> 操作会跳过空格。
如果你想保留所有字符然后做(在你读它之前):
ifs >> std::noskipws;
您可能还需要以二进制模式打开文件。不过我觉得没必要。
如果你想准确地读入一个字符串中的两个字节,你可以使用它来代替 getline:
std::string st;
st.resize(2);
ifs.read(&st[0], st.size());
[更新]这应该有效:
int pix[3]; // not an unsigned char
...
ifs >> pix[0] >> pix[1] >> pix[2];
而不是:
ifs.read(reinterpret_cast<char *>(pix), 3);
就像您对宽度和高度所做的那样?
ifs >> w >> h >> max;
我正在尝试让我的代码读取 PPM 图像 (P3),但它没有正常工作。这个想法是获取 3 个无符号字符并将它们存储在 RGB 中。但目前它只会导致取第一个字符而忽略其余字符。
Image Image::readImg(std::string const &filename) {
std::ifstream ifs;
ifs.open(filename.c_str(), std::ios::binary);
Image _in;
try {
if (ifs.fail()) {
throw("Can't open input file");
}
std::string header;
int w, h, max;
ifs >> header;
if (strcmp(header.c_str(), "P3") != 0) throw("Can't read input file");
ifs >> w >> h >> max;
_in.init(w, h);
ifs.ignore(256, '\n');
unsigned char pix[3];
for (int i = 0; i < h; ++i){
for (int j = 0; j < w; ++j){
ifs.read(reinterpret_cast<char *>(pix), 3);
_in.pixels[i][j].R = pix[0];
_in.pixels[i][j].G = pix[1];
_in.pixels[i][j].B = pix[2];
}
}
std::cout << "|" << _in.pixels[0][0].R << " " << _in.pixels[0][0].G << " " << _in.pixels[0][0].B << "|";
ifs.close();
}
catch (const char *err) {
fprintf(stderr, "%s\n", err);
ifs.close();
}
return _in;
}
请注意,std::cout 应该在我的场景中输出 |186 0 255|,但我却得到了 |1 8 6|。
编辑: 文件 (original.ppm) 在 Notepad++ 中打开时,看起来像这样 (UNIX / UTF-8):
P3
1024 768
255
186 0 255 186 0 255 186 0 255 186 0 255 186 0 255 186 0 255 186 1 255
186 1 254 186 1 254 185 2 254 185 2 254 185 1 254 185 2 253 185 3 253
185 2 252 185 3 252 185 3 252 185 3 252 185 3 251 184 4 251 184 4 251
184 4 251 184 4 251 184 5 250 184 5 250 183 5 250 183 6 249 183 6 249
183 6 249 183 6 248 183 7 249 183 7 249 183 7 248 183 7 247 183 8 247
182 7 247 182 8 246 183 9 247 183 9 246 183 9 246 182 9 246 181 9 246
182 9 246 181 10 245 182 10 245 181 10 244 181 10 245 181 11 244 181 11 244
...
结果应该是: _in.pixels[0][0].R = 186 _in.pixels[0][0].G = 0 _in.pixels[0][0].B = 255 并继续收集文件中所有像素的RGB。
默认情况下,在流中使用 >> 操作会跳过空格。
如果你想保留所有字符然后做(在你读它之前):
ifs >> std::noskipws;
您可能还需要以二进制模式打开文件。不过我觉得没必要。
如果你想准确地读入一个字符串中的两个字节,你可以使用它来代替 getline:
std::string st;
st.resize(2);
ifs.read(&st[0], st.size());
[更新]这应该有效:
int pix[3]; // not an unsigned char
...
ifs >> pix[0] >> pix[1] >> pix[2];
而不是:
ifs.read(reinterpret_cast<char *>(pix), 3);
就像您对宽度和高度所做的那样?
ifs >> w >> h >> max;