waylonis@banana.cis.ohio-state.edu (Mr Waylonis) (02/14/90)
Hi,
I'm having a problem getting ThinkC to accept the following:
procedureX()
{
Str255 myString;
myString = "\pExample string";
}
which a reference book said was correct. I need to be able to set the
string to different values, so I can't say:
Str255 myString = {"\pExample string"};
Any suggestions?
Thanks,
Dan
-=-
Dan Waylonis, resplendent grad student Home Sweet Home:
Ohio State University, Dept. of CS | 2251 Buckley Rd. Cols., OH 43220-4613
2036 Neil Ave., Cols., OH 43210-1277| (614) 459-7326
Email: waylonis@cis.ohio-state.edu | "No matter where you go, there you are."
beard@ux1.lbl.gov (Patrick C Beard) (02/14/90)
In article <77108@tut.cis.ohio-state.edu> <waylonis@cis.ohio-state.edu> writes: #Hi, # #I'm having a problem getting ThinkC to accept the following: # #procedureX() #{ # Str255 myString; # # myString = "\pExample string"; #} # #which a reference book said was correct. At certain times I've used strcpy(myString, "\pExample string"); MPW C certainly allows this, as a length byte and null are generated in MPW C's string constants. I'm not sure if THINK C's have nulls. And obviously this won't work in general for all pascal strings. How about: pstrcpy(StringPtr dest, StringPtr src) { register short len = src[0]; dest[0] = len; /* save length. */ while(len--) *++dest = *++src; } This should be general enough... (please no flames, I composed this here.) ------------------------------------------------------------------------------- - Patrick Beard, Macintosh Programmer (beard@lbl.gov) - - Berkeley Systems, Inc. ".......<dead air>.......Good day!" - Paul Harvey - -------------------------------------------------------------------------------
sdh@flash.bellcore.com (Stephen D Hawley) (02/14/90)
In article <77108@tut.cis.ohio-state.edu> <waylonis@cis.ohio-state.edu> writes: >Hi, > >I'm having a problem getting ThinkC to accept the following: >procedureX() >{ > Str255 myString; > > myString = "\pExample string"; >} Try: procedureX() { char *myString; myString = "\pExample string"; } Str255 is an array type. When you say "Str255 myString" you are actually saying "create an array of 256 characters named myString". When you do the assignment, you are asking Think C to do a Pascal string copy at runtime. This is undefined behavior for arrays in C. My example just does a pointer assignment. Beware that myString is a char * not an unsigned char *. If you declare it as an unsigned char * you will get a type clash, but if you don't you have to be sure to cast the first byte to an unsigned char if you use it as a length (otherwise it'll get sign extended). Steve Hawley sdh@flash.bellcore.com A noun's a special kind of word. It's ev'ry name you ever heard. I find it quite interesting, A noun's a person place or thing.
rotberg@dms.UUCP (Ed Rotberg) (02/15/90)
From article <77108@tut.cis.ohio-state.edu>, by waylonis@banana.cis.ohio-state.edu (Mr Waylonis): > Hi, > > I'm having a problem getting ThinkC to accept the following: > > procedureX() > { > Str255 myString; > > myString = "\pExample string"; > } > > Any suggestions? Offhand, I can't say whether the above syntax is legal or not as I'm more of a "working man's" C programmer, and not a theoretician. However, as the compiler dosn't like it, you need to write a small routine like: void pStrcpy(dst,src) /* I myself like (src,dst) but it's just not C!! */ Str255 *dst,*src; { int i; for(i = (unsigned char)(*src); i >=0; --i) /* cast whenever in doubt */ *dst++ = *src++; } Then myString = "\pExample string"; becomes pStrcpy(myString,"\pExample string"); Not precisely elegant, but it'll work. - Ed Rotberg -
omullarn@oracle.oracle.com (Oliver Mullarney) (02/15/90)
In article <20011@bellcore.bellcore.com> sdh@flash.UUCP (Stephen D Hawley) writes: >In article <77108@tut.cis.ohio-state.edu> <waylonis@cis.ohio-state.edu> writes: >>Hi, >> >>I'm having a problem getting ThinkC to accept the following: >>procedureX() >>{ >> Str255 myString; >> >> myString = "\pExample string"; >>} > >Try: > >procedureX() >{ > char *myString; > > myString = "\pExample string"; >} > This is just a little dubious; no space is being allocated anywhere, so this should not be used in a general case. It will work for the given situation, but not once you drop up one level on the stack from where the assignment is made (literals are defined on the stack, right?). What I would do is: procedureX() { char *myString = (char *)malloc(256); /* can index 0 to 255 */ strcpy(myString,"Example string"); c2pstr(myString); /* effectively turns it into an Str255 */ ... p2cstr(myString); /* unnecessary, but why not be tidy :-) */ free (myString); } This is a little more general, and safe. Oliver | Oliver Mullarney | "Death wears a big hat, | | Oracle Corporation | 'cos he's a big bloke" | | omullarn@oracle.com | Tokyo Storm Warning, Elvis Costello | --------------- "Universally acknowledged to work just fine" ----------------
dowdy@apple.com (Tom Dowdy) (02/16/90)
[ several people give suggestions for copying strings via procedures ] Here are some macros for doing similar things: #define PSTRCPY(P1, P2) BlockMove(P2, P1, P2[0]+1) and also #define PSTRCAT(P1, P2) \ BlockMove(&P2[1], &P1[(P1[0]+1)], P2[0]); \ P1[0] += P2[0]; Some cautions about these, however. First off, neither of them do any kind of error checking. In the first case, this usually isn't a problem when you are tossing Str255s around. In the second case, things *can* get more hairy, but this is the case of having strong requirements on the caller rather than in the called routine. As long as one is aware of what is going on, this isn't a problem. The second macro probably isn't the most efficient way to code this, and no doubt some C person will tell me as much, but I almost never use PSTRCAT except in debugging code. However, there is one *serious* problem to watch out for. I hope this is the correct reason for this. In MPW C, the "\p" directive isn't evaulated until late in the code gen, so at the macro level, taking the first position in the array as a length results in the value '\' rather than in the length of the string. The result of this is that you can't do PSTRCPY(myString, "\pTesting"); This can be annoying, but since all my strings come out of resources (as they should in final code), I work around it when I have to. I don't know if this also happens in Think C, it may be part of the ANSI C spec. Tom Dowdy Internet: dowdy@apple.COM Apple Computer MS:81EQ UUCP: {sun,voder,amdahl,decwrl}!apple!dowdy 20525 Mariani Ave AppleLink: DOWDY1 Cupertino, CA 95014 "The 'Ooh-Ah' Bird is so called because it lays square eggs."
tim@hoptoad.uucp (Tim Maroney) (02/16/90)
In article <1990Feb14.210352.28118@oracle.com> omullarn@oracle.com (Oliver Mullarney) writes: >>procedureX() >>{ char *myString; >> myString = "\pExample string"; >>} >> > >This is just a little dubious; no space is being allocated anywhere, so >this should not be used in a general case. It will work for the given >situation, but not once you drop up one level on the stack from where >the assignment is made (literals are defined on the stack, right?). No, generally speaking, they're allocated in global space. You can give a compiler directive in MPW to make them allocated in code space, though; this is useful mostly in XCMDs and XFCNs. I don't know of any Mac C compilers that put string literals on the stack. Think about the code the compiler would have to generate and you'll see why. Of course, all the discussion here has missed the real point, which is that you almost always should avoid string literals on the Mac (except in XCMDs and XFCNs, where they're considered kosher, because someone moving the XCMD into another stack may forget to move any associated 'STR ' and 'STR#' resources, and they may have to be renumbered to avoid conflicts). Instead, use GetString and GetIndString to get your string constants; this will make it much easier to move your code to other languages. However, in the immortal words of Amanda Walker, if you're making mud pies, it doesn't matter how much sugar you use; if you're just doing a quick and dirty utility or something which you are reasonably sure will always be local to your site, go ahead and use the literals. Finally, the most useful string manipulation utility is BlockMove. Use it often and without compunction. -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com FROM THE FOOL FILE: "The negro slaves of the South are the happiest, and, in some sense, the freest people in the world. The children and the aged and infirm work not at all, and yet have all the comforts and neccessaries of life provided for them." -- George Fitzhugh, CANNIBALS ALL! OR, SLAVES WITHOUT MASTERS, 1857