So far I can read every line and print it out to the console:
void readFile(){
string line;
ifstream myfile("example1.pgm");
if (myfile.is_open()){
while (myfile.good()){
getline (myfile,line);
cout << line;
}
}
However a pgm file apparently will always have the following at the start before the data:
P2
# test.pgm
24 7
15
How can i adapt my code so that it checks that "P2" is present, ignores any comments (#), and stores the variables and subsequent pixel data?
I'm a bit lost and new to c++ so any help is appreicated.
Thanks
There are a lot of different ways to parse a file. For something like this, you could look at the answers on this site. Personally, I would go with a loop of getline() and test/parse every line (stored in the variable "line"), you can also use a stringstream since it is easier to use with multiple values :
Idea
First line : test that P2 (Portable graymap) is present, maybe with something like
Second line : do nothing, you can go on with the next getline()
Third line : store the size of the image; with a stringstream you could do this
Following lines : store the pixel data until you reach the end of the file
Resulting code
You can try this code and adapt it to your needs :
EDIT
Here is a good tutorial on how to use stringstreams.
A way of simplifying PNM (PBM/PGM/PPM) header processing is to build up a header string line-by-line until you have captured all of the requisite data. It doesn't take too much code to do this using only the standard C++ libraries...
This handles comments (if present) and the special-case of PBM (no 'maxsample') -- and it works regardless of whether or not exceptions are enabled on the input stream.
Once you've read the header, reading the image data is usually a simple matter since the format is defined to just be a sequential data dump (which may be either ASCII or binary depending on the 'magic' value). In the case of 16-bit binary-encoded samples, the format specification indicates that "The most significant byte is first" (big endian), so this case may require some platform-specific handling.
As written, this requires C++11 -- probably due to the way I'm using
stringstream
as a temporary.One caveat: In a pathological case, it is possible for this to waste a lot of time/RAM while attempting to read an invalid header -- since the
getline
call isn't inherently bounded. There's a relatively simple solution (replacegetline
with something more robust), but it requires a bit more code.For production-quality applications, consider using libnetpbm.