Archived

This topic is now archived and is closed to further replies.

Megatron

Converting int's to char* 's

Recommended Posts

Megatron    122
I have a font rendering function that takes a char* as its first argument. The trouble is, I want to print out a number that has to have operations performed on it. So if I have something like int hitPoints = 100; and I want to change hitPoints into char* text so I can call RenderFont(text,.....); What should I do?

Share this post


Link to post
Share on other sites
merlin9x9    174
I'm assuming that you (Megatron) aren't aware that char* parameters are used to pass the address of the first character of a string—a C-style string (array of characters). So, you want to convert an int to a [C-style] string. That's what you'll ask for. It's not just pedanticism because the answer to your question, exactly how it was asked, is: (char*)myint .


[edited by - merlin9x9 on April 29, 2002 9:40:55 PM]

Share this post


Link to post
Share on other sites
IndirectX    122
quote:
Original post by merlin9x9
It''s not just pedanticism because the answer to your question, exactly how it was asked, is: (char*)myint .


Nope.

"I want to change hitPoints into char* text"

Changing hitPoints into text is not the same as casting it to char *.

Share this post


Link to post
Share on other sites
merlin9x9    174
That''s how you phrased it in your message subject line, and that''s what I meant. But from what I actually said, you''re absolutely right.

Share this post


Link to post
Share on other sites
I hate std::string. It sucks. What were they injecting into themselves when they came up with the idea of using the << and >> operators? Oluseyi's std version is so confusing and nonintuitive. That's what I don't use the STL.

~CGameProgrammer( );

[edited by - CGameProgrammer on April 29, 2002 12:19:07 AM]

Share this post


Link to post
Share on other sites
sjelkjd    171
quote:
Original post by CGameProgrammer Oluseyi's std version is so confusing and nonintuitive. That's what I don't use the STL.



    
string tostring(int n)
{
ostringstream out;
out<<n;
return out.str();
}

Hide that away somewhere and all you'll ever have to see is tostring()...happy?

Oh, and std::string doesn't use << and >>. That would be STREAMS you're talking about.

[edited by - sjelkjd on April 29, 2002 12:39:43 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
quote:

"I want to change hitPoints into char* text"




  
#!/usr/bin/perl
$hitPoints = 666;
$text = "$hitPoints";


Ah.

Share this post


Link to post
Share on other sites
quote:
Your loss.


No, I wrote my own string class. It''s not hard, is simple to use, and I know exactly what it''s doing. Same with my file class.

string<64> text = hitPoints; // Done.


~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
and then I wrote map, vector, list, sort, remove_if, bind2nd, less, equal_to.... yeah and then I died of old age. But my heirs don''t have to use those shift operators for IO!

Share this post


Link to post
Share on other sites
(CGameProgrammers equips his flamethrower)

Good point. Those have been programmed already, why redo it just because I''d prefer it done differently? In fact, why did I even write my own Direct3D and OpenGL wrappers when others already exist? Hey, wait a second - I''m working on a 3D engine! Well, how stupid. There are tons of 3D engines already so there''s no point writing my own. Why am I even being sarcastic when there''s plenty of sarcastic people already?

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Oluseyi    2103
quote:
Original post by CGameProgrammer
In fact, why did I even write my own Direct3D and OpenGL wrappers when others already exist? Hey, wait a second - I''m working on a 3D engine! Well, how stupid. There are tons of 3D engines already so there''s no point writing my own.

The streams and string classes are part of the C++ language. Your 3D engine (and those of others) are not. Ergo, anybody using C++ has access to the same fundamental string, file, stream and other classes, but would specifically need to obtain your own libraries to compile your code.

There are advantages to standard methods for common tasks, which is why those classes were written and made a part of the standard.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
Xai    1848
Please note ... itoa() is NOT in the language proper ... and never has been.

Complier vendors provided it, because it looked like a good match to atoi. But it is not. atoi() is a way to get the same conversions performed by the compiler on constans - ie 0x10 is 16, 010 is 8, and 10 is 10, etc.

itoa() had some radix functions and such built in, which are really cool, but they decided that the functionallity is better server using sprintf in c, and streams in c++.

so new compilers do not usually ship with itoa() anymore.

The streams are awesome because you can do ALL the stuff you would do when sending it to a text file ... like


  
stringstream buffer;
buffer << "name: " << name << ", hp: " << hitpoints;


and then get the formated c-string using str(), for use in functions like RenderFont() ...

this is no better or worse than sprintf() ... you use whichever suits you at the time .... but the reason it matters is that it makes available to you all the mutators and other streaming functions you have written ... say you write your own << operator to pipe out a character to one line of a file ... well now you can render that on the screen with


  
stringstream buffer;
buffer << myCharacter;
RenderFont(buffer.str());


see ... you only need to write the one << and >> operator per class, and you can read and write them to files, to strings, and across the network.

Good Luck.

Share this post


Link to post
Share on other sites
I can see the appeal of using STL if you haven''t already written your own classes for the basics, but I have, and haven''t ever learned STL, though I recently bought Game Programming Gems which has chapters on it (or maybe I''m thinking of some other recent book, I forget). But I still hate its syntax. I think

string buffer = "name: " + name + ", hp: " + hitPoints;

is better than the STL equivalent. But STL is designed to have a common interface for all objects - it wouldn''t look right writing data to a file using the + operator.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
msn12b    390
quote:
Original post by CGameProgrammer
I can see the appeal of using STL if you haven''t already written your own classes for the basics, but I have, and haven''t ever learned STL, though I recently bought Game Programming Gems which has chapters on it (or maybe I''m thinking of some other recent book, I forget). But I still hate its syntax. I think

string buffer = "name: " + name + ", hp: " + hitPoints;

is better than the STL equivalent. But STL is designed to have a common interface for all objects - it wouldn''t look right writing data to a file using the + operator.

~CGameProgrammer( );




Jeez, you don''t get it, do you?

One main advantage of having any standard library comes from using a consistent interface for every utility class/function/algorithm/etc. you use. By ensuring a standard interface accross various generic components, you can specialize/optimize specific instances of a particular component (say, a custom type that mimics std::map but with better performance for your application) and know that you won''t have to recompile everything that uses it, as long as you maintain the standard interface.

This isn''t a bad thing.

MSN

Share this post


Link to post
Share on other sites
SabreMan    504
quote:
Original post by CGameProgrammer
I can see the appeal of using STL if you haven't already written your own classes for the basics, but I have, and haven't ever learned STL, though I recently bought Game Programming Gems which has chapters on it (or maybe I'm thinking of some other recent book, I forget).

It sounds like your unwillingness to use the Standard Library is down to some religious mistrust rather than any sound technical criteria. You are welcome to your opinions, but it's not really a good idea to push that sort of view onto newbies.


[C++ FAQ Lite | ACCU | Boost | Python]

[edited by - SabreMan on May 1, 2002 4:21:56 AM]

Share this post


Link to post
Share on other sites
Dire.Wolf    122
The reason it is better to use streams over sprintf() is type-safety.

char* fmttext;
int num;

sprintf(ftmtext, "%s", num);

I''ve seen people try the code above and be surprised by the results. There are two mistakes above: 1) didn''t allocate memory for fmttext, 2) didn''t use the correct format specifier.

C++ Streams are much safer to work with:

stringstream fmttext;
int num;

fmttext << num;

As another posted noted, if you provide your classes with the << operator (and >> operator) you can implement proper class serialization to and from streams.

All that said and done, I must admit that sprintf() appears to be much easier to use and looks nicer (code-wise.) It just isn''t as good a solution as using stringstream.

Dire Wolf
www.digitalfiends.com

Share this post


Link to post
Share on other sites
davepermen    1047
first time looking at stl i got scared:
why "vector", vector is a 3dpoint!
why >> <<, those are bitshifts!
etc..
but one time i got bored by coding my own linked lists, by aranging the data etc.. and i''ve seen more and more code using those fancy vectors..

vector dyn_int_array;
dyn_int_array.push_back(10);
dyn_int_array.push_back(20);
dyn_int_array.push_back(47);
dyn_int_array.push_back(135);

and the first time i used it was in a raytracer wich should handle all my spheres..

and i never went back..

i''m learning more and more of it, and newest i learned the stringstreams... as the std::string had no feature for adding other stuff than strings to itself, and i wanted ints as well..

and when you''re finally at maps or hash_maps, you simply love it..

AddUser(char* name,UserData& data) {
userlist[name] = data;
}

ever seen nicer code?


my tip:
strstream str;
str << int_value;
TextOut(str.str());


why reinwenting a wheel for stringclasses if you could reintwent a gamenengine and sell it for millions?

anyone wants to buy a stringclass?

newest news:
john carmack dropped doom3, he now codes his own string-class with operator + instead of operator <<.. its now in every gamestore, for only 50$:

ID SOFTWARE
STRING 3
requirements: geforce3+ for perpixellighting and shadowingeffects..

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Let me clarify: I do not use sprintf. I use my own string class. That class uses sprintf internally, but I don't use it directly. The class does all type-safety checking. Even if I did use STL, I would simply wrap std:string within my own string class probably. Similarly, I don't use the Win32 API directly for application/window creation; I wrote a wrapper for it.

My string class suits all my purposes, although at the moment it's only static strings. When I start writing my GUI I'll add dynamic capabilities to it.

If you're curious, here it is. Well, first I'll show how it's used:

string<64> Test = "This is a test string";
string<64> ThisIsA = Test.Sub( 0, 9 );
char LetterS = Test[3];
char* PointerToTheStringItself = Test;

Test.Make( STRING_LOWERCASE ); // this is a test string
Test.Make( STRING_UPPERCASE ); // THIS IS A TEST STRING
Test.Make( STRING_NOTCASESENSITIVE );
if( Test == "this IS a TEST string" )
{
this does evaluate to true
}

And this is the class itself... not a replacement for STL, but it suits my purposes:

    
template <UINT Size> class string
{
friend string;

public:

string ( )
{
m_Size = Size;
m_Compare = strcmp;
m_Length = 0;
memset( m_String, 0, Size );
}

string ( char* Params, ... )
{
static va_list Marker;

va_start( Marker, Params );
vsprintf( m_String, Params, Marker );
va_end( Marker );

m_Size = Size;
m_Compare = strcmp;
m_Length = strlen( m_String );
}

string ( const char Letter )
{
m_Size = Size;
m_Compare = strcmp;
m_String[0] = Letter;
m_String[1] = 0;
m_Length = 1;
}

string ( const int Number )
{
m_Size = Size;
m_Compare = strcmp;
sprintf( m_String, "%ld", Number );
m_Length = strlen( m_String );
}

string ( const double Number )
{
m_Size = Size;
m_Compare = strcmp;
sprintf( m_String, "%f", Number );
m_Length = strlen( m_String );
}

string& operator () ( char* Params, ... )
{
static va_list Marker;

va_start( Marker, Params );
vsprintf( m_String, Params, Marker );
va_end( Marker );
m_Length = strlen( m_String );

return *this;
}

inline operator bool ( ) const
{
return m_String[0] ? true : false;
}

inline operator char* ( ) const
{
return (char*)m_String;
}

inline operator char ( ) const
{
return m_String[0];
}

inline operator int ( ) const
{
return atol( m_String );
}

inline operator double ( ) const
{
return atof( m_String );
}

inline string& operator = ( string& String )
{
strcpy( m_String, String.m_String );
m_Length = String.m_Length;

return *this;
}

inline string& operator = ( char* String )
{
strcpy( m_String, String );
m_Length = strlen( String );

return *this;
}

inline string& operator = ( char Letter )
{
m_String[0] = Letter;
m_String[1] = 0;
m_Length = 1;

return *this;
}

inline string& operator = ( int Number )
{
sprintf( m_String, "%ld", Number );
m_Length = strlen( m_String );

return *this;
}

inline string& operator = ( double Number )
{
sprintf( m_String, "%f", Number );
m_Length = strlen( m_String );

return *this;
}

inline string& operator += ( string& String )
{
strcat( m_String, String.m_String );
m_Length += String.m_Length;

return *this;
}

inline string& operator += ( char* String )
{
strcat( m_String, String );
m_Length = strlen( m_String );

return *this;
}

inline string& operator += ( char Letter )
{
m_String[m_Length] = Letter;
m_Length ++;
m_String[m_Length] = 0;

return *this;
}

inline string& operator += ( int Number )
{
sprintf( m_String, "%s%ld", m_String, Number );
m_Length = strlen( m_String );

return *this;
}

inline string& operator += ( double Number )
{
sprintf( m_String, "%s%f", m_String, Number );
m_Length = strlen( m_String );

return *this;
}

inline string operator + ( string& String )
{
string Temp;

sprintf( Temp.m_String, "%s%s", m_String, String.m_String );
Temp.m_Length = m_Length + String.m_Length;

return Temp;
}

inline string operator + ( char* String )
{
string Temp;

sprintf( Temp.m_String, "%s%s", m_String, String );
Temp.m_Length = strlen( Temp.m_String );

return Temp;
}

inline string operator + ( char Letter )
{
string Temp;

sprintf( Temp.m_String, "%s%c", m_String, Letter );
Temp.m_Length = m_Length + 1;

return Temp;
}

inline string operator + ( int Number )
{
string Temp;

sprintf( Temp.m_String, "%s%ld", m_String, Number );
Temp.m_Length = strlen( Temp.m_String );

return Temp;
}

inline string operator + ( double Number )
{
string Temp;

sprintf( Temp.m_String, "%s%f", m_String, Number );
Temp.m_Length = strlen( Temp.m_String );

return Temp;
}

inline bool operator == ( char* String )
{
return m_Compare( m_String, String ) ? false : true;
}

inline bool operator != ( char* String )
{
return m_Compare( m_String, String ) ? true : false;
}

inline bool operator <= ( char* String )
{
return m_Compare( m_String, String ) <= 0;
}

inline bool operator >= ( char* String )
{
return m_Compare( m_String, String ) >= 0;
}

inline bool operator < ( char* String )
{
return m_Compare( m_String, String ) < 0;
}

inline bool operator > ( char* String )
{
return m_Compare( m_String, String ) > 0;
}

inline UINT Length ( )
{
return m_Length;
}

inline UINT MaxSize ( )
{
return m_Size;
}

inline string Sub ( UINT Index, UINT Length )
{
string Temp;

memcpy( Temp.m_String, &m_String[Index], Length );
Temp.m_Length = Length;

return Temp;
}

void Make ( UINT Change )
{
UINT I;

switch( Change )
{
case STRING_NOTCASESENSITIVE:

m_Compare = stricmp;
break;

case STRING_UPPERCASE:

for( I = 0; I < m_Length; I ++ )
if( m_String[I] >= 97 && m_String[I] <= 122 )
m_String[I] -= 32;
break;

case STRING_LOWERCASE:

for( I = 0; I < m_Length; I ++ )
if( m_String[I] >= 65 && m_String[I] <= 90 )
m_String[I] += 32;
break;

default:

m_Compare = strcmp;
}
}

UINT Hex ( )
{
static UINT H;
static UINT S;

H = 0;
S = 0;

if( m_Length > 2 && m_String[0] == '0' && (m_String[1] == 'x' || m_String[1] == 'X') )
{
for( long N = m_Length-1; N >= 2; N -- )
{
if( m_String[N] >= 48 && m_String[N] <= 57 )
H += UINT(m_String[N] - 48) << (S<<2);
else if( m_String[N] >= 65 && m_String[N] <= 70 )
H += UINT(m_String[N] - 55) << (S<<2);
else if( m_String[N] >= 97 && m_String[N] <= 102 )
H += UINT(m_String[N] - 87) << (S<<2);

S ++;
}

return H;
}
else if( m_Length >= 2 && m_String[m_Length-1] == 'h' || m_String[m_Length-1] == 'H' )
{
for( long N = m_Length-2; N >= 0; N -- )
{
if( m_String[N] >= 48 && m_String[N] <= 57 )
H += UINT(m_String[N] - 48) << (S<<2);
else if( m_String[N] >= 65 && m_String[N] <= 70 )
H += UINT(m_String[N] - 55) << (S<<2);
else if( m_String[N] >= 97 && m_String[N] <= 102 )
H += UINT(m_String[N] - 87) << (S<<2);

S ++;
}

return H;
}

return atol( m_String );
}

bool GetPath ( string<256>* Path, string<256>* Directory, string<256>* Filename, string<256>* Name, string<256>* Extension )
{
string<256> TempDir;
char CWD [256];
char OWD [256];

# ifdef APPLICATION_DEBUG
if( !Path || !Directory || !Filename || !Name || !Extension )
return false;
# endif

_getcwd( OWD, 256 );

for( long N = (long)m_Length - 1; N >= 0; N -- )
{
if( m_String[N] == '\\' )
{
TempDir = Sub( 0, N+1 );
*Filename = Sub( N+1, m_Length - N - 1 );

if( _chdir( (char*)TempDir ) )
return false;

_getcwd( CWD, 256 );

*Directory = CWD;
_chdir( OWD );

break;
}
else if( !N )
{
*Directory = OWD;
*Filename = m_String;
}
}

if( (*Directory)[Directory->Length()-1] != '\\' )
*Directory += '\\';

*Path = *Directory + *Filename;
*Name = *Filename;
*Extension = "";

for( N = (long)Filename->Length() - 1; N >= 0; N -- )
{
if( (*Filename)[N] == '.' )
{
*Name = Filename->Sub( 0, N );
*Extension = Filename->Sub( N+1, Filename->Length() - N - 1 );
return true;
}
}

return true;
}

private:

char m_String [Size];
UINT m_Length;
UINT m_Size;
int (* m_Compare ) ( const char*, const char* );
};


~CGameProgrammer( );

EDIT: Made some formatting changes.

[edited by - CGameProgrammer on May 1, 2002 2:05:47 PM]

Share this post


Link to post
Share on other sites
DrPizza    160
quote:
Original post by CGameProgrammer
I hate std::string. It sucks.

No it doesn''t.

quote:
What were they injecting into themselves when they came up with the idea of using the << and >> operators?

They didn''t. Strings can''t use those operators. Strings are not streams.

quote:
Oluseyi''s std version is so confusing and nonintuitive.

How so? A stringstream is a stream that rather than being backed by a file or other buffer. This allows one to use the familiar stream formatted I/O, using a dynamic string as the backing store. If you know what strings and streams are -- which apparently you don''t -- it''s incredibly intuitive.

quote:
That''s what I don''t use the STL.

Your loss.

Share this post


Link to post
Share on other sites