尝试从 PGM 文件读取像素数据时出错

问题描述 投票:0回答:1

我正在尝试实现一个 C++ 类来读取 PGM 文件。我可以毫无问题地读取文件头(幻数、宽度、高度和最大值),但是当我尝试读取像素数据时,出现与使用

stoi
进行字符串转换相关的错误。

我现在得到的代码:

        while(getline(file, line_pixels)) {
            if(line_pixels.size() > 0 && line_pixels.at(0) != '#') {
                std::stringstream ss(line_pixels);
                std::string value;
                while(getline(ss, value, ' ')) {
                    pixel p;
                    p.r = p.g = p.b = stoi(value) / this->max_value;
                    v.emplace_back(p);
                }
            }
        }

错误上线:

                    p.r = p.g = p.b = stoi(value) / this->max_value;

程序在读取空格时出现问题(它应该跳过这些)。以下代码是可以编译以重现错误的程序:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

void read(std::string file_name);

struct Pixel {
  float r, g, b;
};
typedef struct Pixel pixel;

class Image {
private:
    int max_value;
    std::vector<std::vector<pixel>> pixels;
public:
    void read(std::string file_name) {
        std::ifstream file(file_name);
        std::string line_one, line_two, line_three, line_pixels;

        char magicNumber;
        std::string width, height;

        while(getline(file, line_one)) {
            if(line_one.size() > 0 && line_one.at(0) != '#') {
                magicNumber = line_one.at(1);
                break;
            }
        }

        while(getline(file, line_two)) {
            if(line_two.size() > 0 && line_two.at(0) != '#') {
                std::stringstream ss(line_two);
                getline(ss, width, ' ');
                getline(ss, height, ' ');
                break;
            }
        }

        while(getline(file, line_three)) {
            if(line_three.size() > 0 && line_three.at(0) != '#') {
                this->max_value = stoi(line_three);
                break;
            }
        }

        if(magicNumber == '2') {
            std::vector<pixel> v;

            while(getline(file, line_pixels)) {
                if(line_pixels.size() > 0 && line_pixels.at(0) != '#') {
                    std::stringstream ss(line_pixels);
                    std::string value;
                    while(getline(ss, value, ' ')) {
                        pixel p;
                        p.r = p.g = p.b = stoi(value) / this->max_value;
                        v.emplace_back(p);
                    }
                }
            }

            int h = stoi(height), w = stoi(width);

            int index = 0;
            for(int i=0; i<h; i++) {
                std::vector<pixel> row;
                for(int j=0; j<w; j++) row.push_back(v[index++]);
                this->pixels.push_back(row);
            }
        }
    }
};

int main(int argc, char ** argv) {
    Image img;
    img.read("lena.ascii.pgm");
    return 0;
}

为了测试这个程序,我使用这个 pgm 图像。谁能告诉我这里出了什么问题吗?

c++ ifstream pgm
1个回答
0
投票

这是跳过空格的修复方法(我只包含读取宽度和高度的块),例如:

     while (getline(file, line_two)) {
        if (line_two.size() > 0 && line_two.at(0) != '#') {
            std::stringstream ss(line_two);
            getline(ss, width, ' ');
            while (ss.peek() == ' ') // skip spaces
                ss.get();
            getline(ss, height, ' ');
            break;
        }
    }

然后要解决 stoi 问题,这又是因为实际值之间有多个空格,因此解析后的值为空,要解决此问题,您只需在将其传递给 stoi 之前检查是否为空字符串,如下所示:

       while (getline(file, line_pixels)) {
            if (line_pixels.size() > 0 && line_pixels.at(0) != '#') {
                std::stringstream ss(line_pixels);
                std::string value;
                while (getline(ss, value, ' ')) {
                    if (value.size() > 0)
                    {
                        pixel p;
                        p.r = p.g = p.b = stoi(value) / this->max_value;
                        v.emplace_back(p);
                    }
                }
            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.