简体   繁体   中英

C++ .obj parser face

Struggling passing the face values of a .obj file to a vector.

f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2

That is what i need to store, but

f 5//1 1//1 4//1
f 5//1 4//1 8//1
f 3//2 7//2 8//2

It can sometimes be like that and i don't know how to get round the problem thanks.

Here's an example that uses boost::tokenizer I use stdin to read input (all the values after the 'f'), and then I simply output the values to the terminal. I'm sure you can modify this to read from a file and place the values where you need them.

Example 1

#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;

void ParseFace(const string& face);
int main(){
  cout << "Input a string: " << endl;
  string s;
  getline(cin,s);
  ParseFace(s);
  return 0;
}

void ParseFace(const string& face){
 boost::char_separator<char> sep(" /");
 boost::tokenizer<boost::char_separator<char> > tokens(face, sep);
 for(tokenizer<boost::char_separator<char> >::iterator beg=tokens.begin(); beg!=tokens.end();++beg){
   cout << *beg << "\n";
 }
}

Sample output:

Input a string: 
3/5/2 7/6/2 8/7/2
3
5
2
7
6
2
8
7
2

Input a string: 
5//1 1//1 4//1
5
1
1
1
4
1

Example 2

Take note of the line boost::char_separator<char> sep(" /"); This is the specifier for all the tokens that will be counted as valid separators. It may be more convenient in your case to change this to boost::char_separator<char> sep("/"); (no whitespace), and then simply read strings like so:

#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
#include <sstream>
using namespace std;
using namespace boost;

void ParseFace(istringstream& _input);
int main(){
  cout << "Input a string: " << endl;
  string s;
  getline(cin,s);
  istringstream input(s);
  char isFace = 'v';
  input >> isFace;
  if (!input.fail()){
    if (isFace == 'f')
      ParseFace(input);
  }
  return 0;
}

void ParseFace(istringstream& _input){
  string nextVal;
  _input >> nextVal;
  while(!_input.fail()){
    cout << "Next set: " << endl;
    boost::char_separator<char> sep("/");
    boost::tokenizer<boost::char_separator<char> > tokens(nextVal, sep);
    for(tokenizer<boost::char_separator<char> >::iterator beg=tokens.begin(); beg!=tokens.end();++beg){
      cout << *beg << "\n";
    }
    _input >> nextVal;
  }
}

Sample output:

Input a string: 
f 5/1/1 1/2/1 4/3/1
Next set: 
5
1
1
Next set: 
1
2
1
Next set: 
4
3
1

Input a string: 
f 5//1 1//1 4//1
Next set: 
5
1
Next set: 
1
1
Next set: 
4
1

In this second example I use a string stream to read individual strings from the entire input, and use a rudimentary check to see if the first character is 'f'. This example should also be adaptable for your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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