   Invoking the dreaded ellipses - save me!
  I'm working on a kind of extensive game for which I will be loading lots of different kinds of data from a file; other structures will take this raw data, stored in strings, and convert it into whatever format they need it in.  For example, a color manager might turn this raw string: "255 0 255" into the color pink, by converting each stringized number into an integer.  I could do this with sprintf, but I really, really want to avoid it for obvious reasons (I'm coding in C++, by the way, if you hadn't figured it out yet).  Isn't there a better way?  Actually, my main worry is that I would have to create and destroy a copy of the char* array stored by the strings, since sprintf takes a non-const char* as its buffer.  I'm lazy and don't want to do that.  I tried just writing a wrapper for sprintf to do this for me, until I realized that ellipses are the devil and should be burned at the stake [grin]Any alternatives are appreciated.  Thanks for your time!   
  Looks like you could use a "dator" type variable type.Benifits? you have local copies of variables "int x" and a stringified friendly version "Dator<int> s_x(x)" that refrences the regular copy.Problems? I don't know of a friendly way to handle all variable types, since some variables don't support all the same operators as others.Any class you make (Vector3d, Matrix4, Creature...) need to support afriend stringstream &operator << ( my_type & );so that you can use them with the dator.This is something very similar to the Enginuity code(Here to be exact) for a dator that I haveused. (Sugestions welcome, i really would like to fix the whole need for a seperate derived type just so i can use things like dator<bool>)class BaseDator{protected:BaseDator(){}BaseDator(const BaseDator &b){(*this)=b;}public:virtual BaseDator &operator =(const string &s)=0;virtual BaseDator &operator +=(const string &s)=0;virtual BaseDator &operator -=(const string &s)=0;virtual BaseDator &operator *=(const string &s)=0;virtual BaseDator &operator /=(const string &s)=0;virtual bool operator ==(const string &s)=0;virtual bool operator !=(const string &s)=0;virtual operator string()=0;};//Template classed Dator for use with any type that supports all += -= *= /= interfacestemplate<class T>class Dator : public BaseDator{protected:T& target;T toVal(const string &s){stringstream str;str.unsetf(ios::skipws);str<<s;T res;str>>res;return res;}string toString(const T &val){stringstream str;str.unsetf(ios::skipws);str<<val;return str.str();}public:Dator(T& t) : target(t) {}BaseDator &operator =(const string &s) { target=toVal(s); return *this; }BaseDator &operator +=(const string &s) { target+=toVal(s); return *this; }BaseDator &operator -=(const string &s) { target-=toVal(s); return *this; }BaseDator &operator *=(const string &s) { target*=toVal(s); return *this; }BaseDator &operator /=(const string &s) { target/=toVal(s); return *this; }bool operator ==(const string &s) { return (s==(string)(*this)); }bool operator !=(const string &s) { return (s!=(string)(*this)); }operator T(){ return target; }operator string() { return toString(target); }};//Blank Dator for creation of dators for types that dont support one of the += -= *= /= operatorstemplate<class T>class DatorBlank : public BaseDator{protected:T& target;T toVal(const string &s){stringstream str;str.unsetf(ios::skipws);str<<s;T res;str>>res;return res;}string toString(const T &val){stringstream str;str.unsetf(ios::skipws);str<<val;return str.str();}public:DatorBlank(T& t) : target(t) {}BaseDator &operator =(const string &s) { target=toVal(s); return *this; }BaseDator &operator +=(const string &s) { return *this; }BaseDator &operator -=(const string &s) { return *this; }BaseDator &operator *=(const string &s) { return *this; }BaseDator &operator /=(const string &s) { return *this; }bool operator ==(const string &s) { return (s==(string)(*this)); }bool operator !=(const string &s) { return (s!=(string)(*this)); }operator string() { return toString(target); }};;  Oh, and I don't want to use any third-party libraries, like boost, for this.  I just don't, OK? [smile]And thanks, KulSeran, although that doesn't really look flexible enough for my purposes.Anyways, I need sleep, so please have this question answered by morning, or I'll h4xx0r gamedev.net and deprive you all of the lounge.  Good night!   ;  What you want is the serialization/deserialization pattern. Basically, serialization is the process of converting an object into a byte stream (serial) representation; deserialization goes the opposite direction.A common C++ approach is to do something like this:class Foo{protected:  int a;  float b;public:  // Stuffpublic:  static Foo* Deserialize(std::istream& data);};Foo* Foo::Deserialize(std::istream& data){  int a;  float b;  data >> a;  if(data.fail())    return 0;  data >> b;  if(data.fail())    return 0;  Foo *pNewObject = new Foo;  pNewObject->a = a;  pNewObject->b = b;  return pNewObject;}Essentially, you want to use a common data format to store your serialized data. I usually use std::istream because it's trivial to read from files and stringstreams that way. The object's static deserializer method will try to load the data and create a valid object from it; if this fails, a null pointer can be returned, or an exception thrown, depending on your preference. Since you want to try and avoid a failed deserialization at all costs, it usually helps to have some kind of "data type indicator" in your data stream that indicates to the code what class it should use to deserialize the following data.Of course it's also trivial to go the other direction, and output a byte stream to represent an object. The serialization process should of course be a non-static member (it makes sense to have a static for deserialization, as you don't have a class instance yet; but it doesn't make sense to serialize a non-instance of the class).   ;Quote:Original post by silverphyre673Invoking the dreaded ellipses - save me!SiCrane is going to have your head on a platter.   ;  String streams.#include <iostream>#include <string>#include <sstream> // <-- zomg!// Really stupid sampleColor ColourManager::create(const std::string& data) {  std::stringstream ss(data);  int r, g, b; char garbage;  if (!(ss >> r >> g >> b) || (ss >> std::ws >> garbage)) {    throw ColourManager::bad_data();  }  return Color(r, g, b);};Quote:Original post by silverphyre673Actually, my main worry is that I would have to create and destroy a copy of the char* array stored by the strings, since sprintf takes a non-const char* as its buffer.  I'm lazy and don't want to do that.  I tried just writing a wrapper for sprintf to do this for me, until I realized that ellipses are the devil and should be burned at the stake [grin]I don't know what gave you the idea you'd have to copy the strings to a non-const string. This is where you'd simply use a const_cast to prevent exactly that.const_cast is something you might want to learn about anyway, even though I'm also quite happy for you to find ways of avoiding the printf idea.[smile]   ;  For converting "255 0 255" to a colour wouldn't you be using sscanf anyway (which doesn't take a non-const char*)?   ;Quote:Original post by silverphyre673Oh, and I don't want to use any third-party libraries, like boost, for this.  I just don't, OK? [smile]Perhaps you should consider it. [wink]Quote:Why should an organization use Boost?In a word, Productivity. Use of high-quality libraries like Boost speeds initial development, results in fewer bugs, reduces reinvention-of-the-wheel, and cuts long-term maintenance costs. And since Boost libraries tend to become de facto or de jure standards, many programmers are already familiar with them.Ten of the Boost libraries are included in the C++ Standard Library's TR1, and so are slated for later full standardization. More Boost libraries are in the pipeline for TR2. Using Boost libraries gives an organization a head-start in adopting new technologies.;Quote:Original post by Will FQuote:Original post by silverphyre673Oh, and I don't want to use any third-party libraries, like boost, for this.  I just don't, OK? [smile]Perhaps you should consider it. [wink]Quote:Why should an organization use Boost?In a word, Productivity. Use of high-quality libraries like Boost speeds initial development, results in fewer bugs, reduces reinvention-of-the-wheel, and cuts long-term maintenance costs. And since Boost libraries tend to become de facto or de jure standards, many programmers are already familiar with them.Ten of the Boost libraries are included in the C++ Standard Library's TR1, and so are slated for later full standardization. More Boost libraries are in the pipeline for TR2. Using Boost libraries gives an organization a head-start in adopting new technologies.Fine, fine.  I clicked your dumb link, and it does look pretty dang professional.  I'm using dev-cpp as my IDE, and I just wanted to know if you know of a place to get a boost devpak (besides devpaks.org, because their link is broken).  Either that, or maybe a tutorial on building libraries from source, or something.  That would probably be a useful skill [smile].  If I can't get boost working, I'll probably just use a stringstream, which, now that I think about it, I have heard of before.  Thanks for your help, everybody!   