简体   繁体   English

ifstream :: read即使使用reinterpret_cast也不读取未签名的字符

[英]ifstream::read not reading unsigned char, even with reinterpret_cast

I am trying to get my code to read a PPM image (P3) and it isn't working as it should. 我正在尝试获取我的代码以读取PPM图像(P3),但它无法正常工作。 The idea is to get a 3 unsigned chars and store them in RGB. 这个想法是获得3个未签名的字符并将其存储在RGB中。 But at the moment it is only resulting in taking the first character and ignoring the rest. 但是目前,这只是导致采用第一个角色而忽略其余角色。

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

Note the std::cout is supposed to output in my scenario |186 0 255|, but instead I get |1 8 6|. 注意在我的场景中应该输出std :: cout | 186 0 255 |,但是我得到的是| 1 8 6 |。


EDIT: The file (original.ppm), when opened in Notepad++, looks like this (UNIX / UTF-8): 编辑:在记事本++中打开文件(original.ppm)时,它看起来像这样(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
...

The result should be: _in.pixels[0][0].R = 186 _in.pixels[0][0].G = 0 _in.pixels[0][0].B = 255 and to continue collecting the RGB of all the pixels in the file. 结果应为:_in.pixels [0] [0] .R = 186 _in.pixels [0] [0] .G = 0 _in.pixels [0] [0] .B = 255,并继续收集RGB文件中所有像素的数量。

Using >> operations in streams skip whitespace by default. 在流中使用>>操作默认情况下会跳过空格。

If you want to preserve all characters then do (before you read from it): 如果要保留所有字符,请这样做(在读取之前):

ifs >> std::noskipws;

you might also need to open the file in binary mode. 您可能还需要以二进制模式打开文件。 But I don't think it is necessary. 但我认为没有必要。

if you want to read exactly two bytes into a string you can use this instead of getline: 如果您想将两个字节准确地读入字符串中,则可以使用它代替getline:

std::string st;
st.resize(2);
ifs.read(&st[0], st.size());

[Updated] This should work: [更新]这应该工作:

int pix[3]; // not an unsigned char
...
ifs >> pix[0] >> pix[1] >> pix[2];

instead of: 代替:

ifs.read(reinterpret_cast<char *>(pix), 3);

Like you do for width and height? 就像您对宽度和高度一样吗?

ifs >> w >> h >> max;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM