From: chh9@ellis.uchicago.edu (Conrad Halling)
Newsgroups: comp.sys.mac.programmer
Subject: Re: How to change an int to a string in Think C?
Date: 23 Jan 93 22:15:40 GMT
Reply-To: chh9@midway.uchicago.edu
Organization: University of Chicago

In article <1993Jan23.191336.877@dunix.drake.edu> 
  kjt001@dunix.drake.edu (Devil Bunny!) writes:

>I'm working with Think C 4.0, and I need to display a number in a dialog
>with ParamText, but I don't know how to do it.

[some lines omitted.]

>I figure I need to change
>the number to a text string first.  I tried using sprintf to do this,
>but it seems to work incorrectly (gives me the wrong number).
>
>The sprintf line is written as follows:
>
>		timeOfClick = (thisclick-lastclick);
>		sprintf(textLine,"\p%d",timeOfClick);
>		ParamText(textLine,"","","");
>
>with the following definitions:
>
>	char		*textLine;
>long int	lastclick,thisclick,timeOfClick;

This doesn't work for the following reasons:

First of all, you have defined textLine as a pointer to a character, but
you haven't actually pointed textLine at anything.  This means that the
textLine variable will be filled with garbage and will point at a random
location in memory.  When you call sprintf(), it will send its output
to that random location, and who knows what you're writing over?

Second, you are giving sprintf() a Pascal string as one of its arguments.
sprintf() expects a C string.  This will definitely mess things up, too.
When you are using the debugger, you can check what's inside your strings
and look at them as C strings or Pascal strings.  This is very handy.

You need to allocate memory for your string.  sprintf requires a pointer
to a C string.  You then convert this to a Pascal string, which is then
passed to ParamText().  Here is one way to do it:

    Str255      textLine;
    long        lastClick,
                thisClick,
                timeOfClick;

    timeOfClick = thisClick - lastClick;
    sprintf( ( char * ) textLine, "%ld", timeOfClick );
    CtoPstr( ( char * ) textLine );
    ParamText( textLine, "\p", "\p", "\p" );

Here are some subtleties:

A Str255 is an array of 256 unsigned chars.  When you say
    Str255           textLine;
what the compiler understands this to mean is:
    unsigned char    textLine[256];

The length byte of a Pascal string is kept in the first byte of the array.  
A standard C string is an array (of any length) of chars which is terminated 
by 0x00.  You have to keep this in mind since the C ANSI functions will 
use C strings, but the Macintosh toolbox expects Pascal strings.  This 
means you have to convert them back and forth.

sprintf expects a pointer to an array of chars; textLine is this pointer.  
You have to cast textLine so the compiler will know that you know what 
you're doing.

When you want to printf a long int, you use "%ld" instead of "%d".

To convert your C string to a Pascal string, use CtoPstr().  (To reverse
the conversion, use PtoCstr().  These functions are provided as a
convenience by THINK C.  They are not in the ANSI standard.)  Since
CtoPstr() expects a pointer to a C string (chars), you must cast your
pointer (which is to an array of unsigned chars).

"\p" tells the compiler to build a constant string as a Pascal string, with
the length byte in front.  If your Pascal string is "\p", the compiler
converts this to a Pascal string consisting only of the length byte, which
is set to zero.  ParamText() expects pointers to arrays of unsigned
characters.  You supply "\p" for the empty strings. Inside Macintosh I-421 
implies that in C you could pass NIL, which is a pointer to memory location
0, which is a convenient way in C of passing a pointer to nothing.

Understanding all this string stuff takes a lot of time.  You will think
you understand it all, and then later you will be totally confused again.
But keep working at it, and pretty soon it won't be a problem any more.

Please excuse any errors.  Knowing me, there probably is one in here
somewhere.  Also, please understand that I'm used to working with THINK C
5.0; I understand THINK C 4.0 works slightly differently (so why aren't
you using the new version??).

-- 
Conrad Halling
c-halling@uchicago.edu
Newsgroups: comp.sys.mac.programmer