[comp.sys.mac.programmer] Str255 in C

jeffb@cs.fau.edu (Jeffrey Boser) (01/13/91)

this might seem like a stupid question, but it has been stumping me for
some time:

how do I assign a string constant to a variable of type Str255?

ie:
        {
        Str255 s;

        s = "\pThis wont work.";
        }


.....Jeff

ml27192@uxa.cso.uiuc.edu (lanett mark) (01/14/91)

jeffb@cs.fau.edu (Jeffrey Boser) writes:

>this might seem like a stupid question, but it has been stumping me for
>some time:

>how do I assign a string constant to a variable of type Str255?

>ie:
>        {
>        Str255 s;

>        s = "\pThis wont work.";
>        }


>.....Jeff

In C the name of an array is actually a pointer to it, so if you _did_
assign "names" you would really only be assigning the pointer (i.e. a=b will 
make a and b both point to b, while real string a is lost).

Use strcpy (in <String.h>): strcpy (a, "This is a string");
I'm not sure doing this with a p-str will work, since it may not have the
requisite 0-byte at the end of the string. Try
strcpy (s, "This will work.");
CToPStr (s); (spelling may be wrong)

CToPStr converts the string _in place_.

Mark Lanett

ksand@Apple.COM (Kent Sandvik) (01/14/91)

In article <1991Jan13.210327.9613@ux1.cso.uiuc.edu> ml27192@uxa.cso.uiuc.edu (lanett mark) writes:
>jeffb@cs.fau.edu (Jeffrey Boser) writes:
>
>>this might seem like a stupid question, but it has been stumping me for
>>some time:
>
>>how do I assign a string constant to a variable of type Str255?
>
>>ie:
>>        {
>>        Str255 s;
>
>>        s = "\pThis wont work.";
>>        }
>
>
>Use strcpy (in <String.h>): strcpy (a, "This is a string");
>I'm not sure doing this with a p-str will work, since it may not have the
>requisite 0-byte at the end of the string. Try
>strcpy (s, "This will work.");
>CToPStr (s); (spelling may be wrong)
>CToPStr converts the string _in place_.

A strcpy(s,"\pThis wirl work."); eliminates the CtoPstr call as well.

Regards,
Kent Sandvik


-- 
Kent Sandvik, Apple Computer Inc, Developer Technical Support
NET:ksand@apple.com, AppleLink: KSAND  DISCLAIMER: Private mumbo-jumbo
Zippy++ says: "The ANSI C++ Standard should be an object oriented model"

mneerach@iiic.ethz.ch (Matthias Ulrich Neeracher) (01/14/91)

In article <1991Jan13.210327.9613@ux1.cso.uiuc.edu>,
ml27192@uxa.cso.uiuc.edu (lanett mark) writes:
> jeffb@cs.fau.edu (Jeffrey Boser) writes:
> >        {
> >        Str255 s;
> 
> >        s = "\pThis wont work.";
> >        } 
> In C the name of an array is actually a pointer to it, so if you _did_
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> assign "names" you would really only be assigning the pointer (i.e. a=b will 
> make a and b both point to b, while real string a is lost).

This is only true for the name of an array *parameter* to a procedure. In the
present case, your statement is wrong. The assignment doesn't work because
C has no array assignment.

Matthias

-----
Matthias Neeracher                                   mneerach@iiic.ethz.ch
   "These days, though, you have to be pretty technical before you can 
    even aspire to crudeness." -- William Gibson, _Johnny Mnemonic_

hanche@imf.unit.no (Harald Hanche-Olsen) (01/15/91)

In article <1991Jan14.184839.11516@agate.berkeley.edu> lindahl@violet.berkeley.edu (Ken Lindahl   642-0866) writes:

   How can we confident that the
   "\p..." in the call to strcpy will be null-terminated? (I don't have the
   THINK docs in front of me, so I apologize in advance if the answer to my
   question is RTFM.)

TFM says, on the middle of p.121:

   Note: Pascal strings are not null terminated.

Apology accepted ;-)

- Harald Hanche-Olsen <hanche@imf.unit.no>
  Division of Mathematical Sciences
  The Norwegian Institute of Technology
  N-7034 Trondheim, NORWAY

oster@well.sf.ca.us (David Phillip Oster) (01/15/91)

For safety, you shouldn't use strcpy on arbitrary pascal strings, since
ones read from resources won't have length bytes. I use:
/* StrMove - copy a pascal string from src to dest
	analagous to BlockMove()
 */
void StrMove(src, dest)Str255 src, dest;{
	BlockMove(src, dest, Length(src) + 1);
}

where Length(s) is defines as:
#define Length(s) ((short) (unsigned char) (s)[0])

so that I can be sure the length will be interpreted as a SIGNED integer
in the range 0..255. Without the casts, 0 - s[0] can return large positive
numbers, due to the nature of unsigned arithmetic in C.
-- 
-- David Phillip Oster - At least the government doesn't make death worse.
-- oster@well.sf.ca.us = {backbone}!well!oster

bin@primate.wisc.edu (Brain in Neutral) (01/16/91)

From article <47171@cci632.UUCP>, by ph@cci632.UUCP (Pete Hoch):
> Giving benefit of the doubt, this reply suffers from less than precise
> wording.  In reality the "\p" is only a place holder for the pascal
> style character count.  I believe the compiler supplies this number
> so it is evaluated very early on.  However this is still a c string!
> That means it is still NULL terminated.

Nope.  Depends on the compiler, so check your manual first.

And if you want your code to be portable, don't write code that
*depends* on the compiler's behavior.
--
Paul DuBois
dubois@primate.wisc.edu

ml27192@uxa.cso.uiuc.edu (lanett mark) (01/16/91)

bin@primate.wisc.edu (Brain in Neutral) writes:

>From article <47171@cci632.UUCP>, by ph@cci632.UUCP (Pete Hoch):
>> Giving benefit of the doubt, this reply suffers from less than precise
>> wording.  In reality the "\p" is only a place holder for the pascal
>> style character count.  I believe the compiler supplies this number
>> so it is evaluated very early on.  However this is still a c string!
>> That means it is still NULL terminated.

>Nope.  Depends on the compiler, so check your manual first.

Well for the case 'Str255 a = "\pThis will work"' the \p is replaced with
the length count _and_ the string is still a null-terminated C string.
So you can do a strcpy and it will work for both Think and MPW.

However, if you just get a pascal string from the toolbox it will _not_ have
the terminator and that _won't_ work (you must use strncpy with n=b[0] (+1?)
). C-created pascal strings are terminated; pascal-created pascal strings are
not (or course).

>And if you want your code to be portable, don't write code that
>*depends* on the compiler's behavior.

Yes.


Mark Lanett

bin@primate.wisc.edu (Brain in Neutral) (01/16/91)

From article <1991Jan15.181224.4809@ux1.cso.uiuc.edu>, by ml27192@uxa.cso.uiuc.edu (lanett mark):
> Well for the case 'Str255 a = "\pThis will work"' the \p is replaced with
> the length count _and_ the string is still a null-terminated C string.
> So you can do a strcpy and it will work for both Think and MPW.

What happens when the stuff between the "\p and the other " is 255
characters long?  What is sizeof (Str255)?  Does it differ, depending
upon circumstances?

Consider the case of statically initialized structures, where the
structure is an Inside Macintosh-defined type that contains a Str255
elements.  Where does that terminating null byte go?  On top of the
next structure element?
--
Paul DuBois
dubois@primate.wisc.edu

keith@Apple.COM (Keith Rollin) (01/16/91)

In article <1991Jan14.142512.24220@clinet.fi> maa@clinet.fi (Miika Asunta) writes:
>2. Instead of using strcopy, which is quite slow, use Toolbox routine
>BlockMove, which is extremely fast:

There are three flavors of copying a variable number bytes under MPW: a
simple loop that copies a range a byte at a time; a smarter loop that
attempts some optimization, and BlockMove().

strcpy() is in the first class. It copies bytes until it copies a 0
byte.  memcpy is in the second class. It copies bytes a byte at a time
until it gets to a longword aligned location, at which time it uses a
ladder of MOVE.L (A1)+,(A0)+ instructions. BlockMove() is a lot
fancier, faster, and also takes into account overlapping byte ranges.

The point of all this is: the fancier a routine is, the higher the
initial overhead. In order to be efficient, the range of bytes copied
must be large enough to make the overhead small. For the simple case of
copying a 10-15 byte string, strcpy() should be faster than BlockMove().
For intermediate ranges, memcpy() should be you choice. For large ranges
(and for overlapping ranges), use BlockMove(). BlockMove() not only has
the largest setup time (which, actually, is not all that siginificant),
but also has the overhead of the trap dispatcher. 

I don't know what the cut-offs are, but I think I saw one routine that
decided to use BlockMove() for anything over 54 bytes. On the other
hand, 80%+ of the calls to BlockMove() are for 1-31 bytes, and 95%+ are
for less than 256 bytes so I imagine that BlockMove() is highly
optimized for those ranges.

-- 
------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc.  ---  Developer Technical Support
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions

maa@clinet.fi (Miika Asunta) (01/17/91)

ml27192@uxa.cso.uiuc.edu (lanett mark) writes:

>maa@clinet.fi (Miika Asunta) writes:
>>2. Instead of using strcopy, which is quite slow, use Toolbox routine
>>BlockMove, which is extremely fast:

>>{
>>Str255 a="\pThis is a test", b;
>>BlockMove(a,b,a[1]+1);
>>}

>I think you meant a[0]+1. This also works for strncpy (i.e.
>strncpy (a, b, b[0]+1) // b must be a pascal string



Yeah. Sorry the typing error... but again... why to use strncpy because
BlockMove() is much faster?

And should the a[0] be coerced somehow in Think C. I haven't had any
problems with this?
-- 
*************************************************************************
* Miika Asunta		        *	Double Basist			*
* internet: maa@clinet.fi       *	     Macintosh Programmer	*
* UUCP: mcsun!fuug!clinet!maa   *					*