0

I am trying read the header for a PGM file, which I found could have the follow variations:

P2
255 255
255

or

P2
255 255 255

or

P2 255 255 255

right now, I got this code:

  std::ifstream file(file_name);
  std::string line_one, line_two, line_three, line_pixels;

  char magicNumber;
  int 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);
      ss >> width >> height;
      break;
    }
  }

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

which works fine for the first variation, but not so much for the other two. I think this could be solve by checking if the end of line was reached after each 'while'/ 'getline' blocks above. Am i right? If so, how to do that?

UPDATE

I try this code, but it is not skipping the lines with comments (starting with #):

  std::ifstream file(file_name);
  std::string line_one, line_two, line_three, line_pixels;

  std::string magicNumber;
  int width, height;

  file >> magicNumber;

  if(file.peek() == '#') {
    std::string comment;
    getline(file, comment);
  }

  file >> width;

  if(file.peek() == '#') {
    std::string comment;
    getline(file, comment);
  }

  file >> height;

  if(file.peek() == '#') {
    std::string comment;
    getline(file, comment);
  }

  file >> this->max_value;

  if(file.peek() == '#') {
    std::string comment;
    getline(file, comment);
  }
Kleber Mota
  • 8,521
  • 31
  • 94
  • 188
  • If the elements are always the same, and your function is specifically for this file type, just explicitly make the reads; as don't try to generalize what you don't need to. Just make four consecutive reads and store them appropriately, it will always work. – sweenish Dec 14 '22 at 15:38
  • 1
    If you have 4 separate variables for those 4 values then you can just do `file >> var1 >> var2 >> var3 >> var4;` – NathanOliver Dec 14 '22 at 15:38
  • @sweenish but I need check if the line is empty or starts wih `#` too. – Kleber Mota Dec 14 '22 at 15:39
  • @NathanOliver but I need check if the line is empty or starts wih # too. – Kleber Mota Dec 14 '22 at 15:39
  • Your question is incomplete, then. Please edit it with enough information so that people can actually help you. Refer to [ask], [mre], and take the [tour]. – sweenish Dec 14 '22 at 15:42
  • @KleberMota You can `peak` at the input before you read it to see if the line is a comment or not. – NathanOliver Dec 14 '22 at 15:42
  • Read a line, and put into an input string stream. Attempt to parse the input string stream using the format `P2 a b c`. If it fails attempt to parse it as `P2 a b`, and all other combinations in turn. If you're missing value, then read the next line and attempt to parse them. In short, try all possible combinations. – Some programmer dude Dec 14 '22 at 15:45
  • @NathanOliver I try do that with the new code I added to the question. Can't figure out what's wrong, because it is not skipping the lines with commentaries. – Kleber Mota Dec 14 '22 at 16:38
  • Can you show what your file looks like for your second code example? – NathanOliver Dec 14 '22 at 17:18
  • @NathanOliver exactly like the example. For test purposes, it is necessary only put the code inside a main function (`int main(int argc, char ** argc) { ... return 0}`) and pass a file test.pgm as parameter (content: `P2 20 20 255`. For catch the issue, it is necessary add a commentary in this file). Here a example: https://pastebin.com/TfmQszmk – Kleber Mota Dec 14 '22 at 17:46

0 Answers0