Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ String tokenisation from 3D .obj files

I'm pretty new to C++ and was looking for a good way to pull the data out of this line.

A sample line that I might need to tokenise is

f 11/65/11 16/70/16 17/69/17

I have a tokenisation method that splits strings into a vector as delimited by a string which may be useful

static void Tokenise(const string& str, vector<string>& tokens, const string& delimiters = " ")

The only way I can think of doing it is to tokenise with " " as a delimiter, remove the first item from the resulting vector, then tokenise each part by itself. Is there a good way to do this all in one?

like image 305
Ben Avatar asked Jul 14 '26 20:07

Ben


2 Answers

I see the question is tagged as C++ but the absolutely easiest way to do this is with scanf

int indices[3][3];
sscanf(buffer, "f %d/%d/%d %d/%d/%d %d/%d/%d", &indices[0][0], &indices[0][1],...);
like image 108
Andreas Brinck Avatar answered Jul 16 '26 13:07

Andreas Brinck


#include <iostream>
#include <sstream>
#include <string>
#include <vector>

class parse_error : public std::exception {};

template< typename Target >
inline Target convert_to(const std::string& value)
{
  std::istringstream iss(value);
  Target target;
  iss >> target >> std::ws;
  if(!iss || !iss.eof()) throw parse_error();
  return target;
}

template< typename T >
inline T read_delimited_value(std::istream& is, char delim)
{
  std::string value;
  std::getline(is,value,delim);
  if(!is) throw parse_error();
  return convert_to<T>(value);
}

template< typename It >
inline void output(std::ostream& os, It begin, It end)
{
  while(begin!=end)
    os << *begin++ << ' ';
}

int main()
{
  std::vector<int> values;
  const std::string line = "f 11/65/11 16/70/16 17/69/17";

  std::istringstream iss(line);
  std::string value;

  std::getline(iss,value,' ');
  if(value!="f" || !iss) throw parse_error();

  while(iss.good()) {
    values.push_back( read_delimited_value<int>(iss,'/') );
    values.push_back( read_delimited_value<int>(iss,'/') );
    values.push_back( read_delimited_value<int>(iss,' ') );
  }

  if(!iss.eof()) throw parse_error();

  output( std::cout, values.begin(), values.end() );
  std::cout << '\n';

  return 0;
}
like image 21
sbi Avatar answered Jul 16 '26 12:07

sbi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!