Because the OBJ does not contain any sort of header, you need some sort of resizable array to hold your vertices, faces, and the other components. In the implementation shown here, everything is loaded into an STL vector, a kind of resizable array.
Each data type has its own structure. Vector3 contains two floats and is used to hold a single vertex position, or vertex normal. Vector2 is a lot like its bigger brother, but holds only two values, perfect for texture coordinates. Last of all is SObjFace, which contains 12 unsigned integers, three for each vertex indexes, texture coord indexes, and normal indexes. Even if all the face variables are not always used, the storage is still there.
Now you are ready to read in the file. The best way to do this is read in one line at a time, check the prefix, and extract the rest of the values using the sscanf function. Each type of value (vertex data, vertex normal, texture coordinate, and face) has its own arrays to hold it. If the loader finds a line that starts with something that does not signify a recognized chunk, it simply reads the line and discards it.
In the CObj class, there are two Boolean values: m_bHasTexCoords and m_bHasNormals. These variables are set to true if a texture coord (for m_bHasTexCoords) or vertex normal line (for m_bHasNormals) is found in the file. Although this does work, it has a few flaws. If for some reason the faces do not come after all the vertex info, the loader will not know what type of face to read and will default to reading vertices only.