palmer@tybalt.caltech.edu (David Palmer) (01/28/88)
In article <4VzXREy00WABE7k0FU@andrew.cmu.edu> rs4u+@andrew.cmu.edu (Richard Siegel) writes: >Additional recommendation: to avoid having to use CtoPstr, just use the "\p" >at the beginning of the string: > > sprintf(tempstring, "%s %f %s %f", "\pthe square of ", x, "is", (x *x)); > DrawString(tempstring); This will not work in any C which I understand. What will be put into tempstring is a null terminated string something like: \016the square of ;&91/z\234dsi 5.00000 is 25.00000 where \016 is the first character in a Pascal string of length 14, ;&91/z\234dsi represents random garbage in the memory following the string, which only ends when there happens to be a byte containing \0, and the remainder is self explanatory. "\pfoo" does not represent a C-string whose first character is '\p', it represents a Pascal string, a one-byte length followed by that many characters. Sprintf is passed an address as its argument, and it expects that address to be of a C-string. By the same token, using a format string of "\p%s %f %s %f" will also fail to work. David Palmer palmer@tybalt.caltech.edu ...rutgers!cit-vax!tybalt.caltech.edu!palmer "Every day it's the same thing--variety. I want something different."
cgw@cadre.dsl.PITTSBURGH.EDU (Gray Watson) (02/02/88)
> sprintf(tempstring, "%s %f %s %f", "\pthe square of ", x, "is", (x *x)); > DrawString(tempstring); Article <5349@cit-vax.Caltech.Edu> stated that the lines above "will not work in any C which [he] understand[s]". Tempstring should, according the article be equal to "\016the square of" followed by random garbage. Well I don't know what version of C you are using but the example WILL work: Sscanf should, like strcat, strcpy, etc. pad any string produced with with a \0 (NULL) character. If it doesn't then it is your compiler's fault. The \p (which for non-Mac routines does insert a \016) is needed for the Mac interface. The first character in the string you send to DrawString should be the value of the length of the string or should be \p or \016: If you are setting up a window title to be "Hello Dolly" the string you should give the OpenWindow call (or whatever it is) should be "\011Hello Dolly" with \011 being the length of "Hello Dolly", but "\pHello Dolly" saves you from recounting the length of the string if you change it a lot. Also when any of the Mac's ROM based file routines return a file name string it doesn't have a \0 (NULL) at the end of the char array but instead the value of first character is the length of the string. To translate from a Mac returned string into correct C format: If file_name[20] is returned I do a: file_name[file_name[0]] = 0; /* punch the string-end with a null */ and refer to the string as &file_name[1] Or if you have memory and speed to burn: If temp[20] is returned: You can do a strncpy(file_name,&temp[1],temp[0]); Which makes file_name be a correct C string with the returned name. Have fun...
jimc@iscuva.ISCS.COM (Jim Cathey) (02/03/88)
In article <943@cadre.dsl.PITTSBURGH.EDU> cgw@cadre.dsl.pittsburgh.edu.UUCP (Gray Watson) writes: >> sprintf(tempstring, "%s %f %s %f", "\pthe square of ", x, "is", (x *x)); >> DrawString(tempstring); > >Article <5349@cit-vax.Caltech.Edu> stated that the lines above "will not work >in any C which [he] understand[s]". Tempstring should, according the article >be equal to "\016the square of" followed by random garbage. > The \p (which for non-Mac routines does insert a \016) is needed for >the Mac interface. The first character in the string you send to DrawString >should be the value of the length of the string or should be \p or \016: > >If you are setting up a window title to be "Hello Dolly" the string you > should give the OpenWindow call (or whatever it is) should be > "\011Hello Dolly" with \011 being the length of "Hello Dolly", > but "\pHello Dolly" saves you from recounting the length of the string > if you change it a lot. To add to the confusion... It is my understanding that in Aztec C (the first place I saw the \p notation) something like "\pfoobar" told the C compiler to count the length of the quoted string and place it in an extra byte at the front of the string. The string was still null terminated as well. Thus "\pthe square of " yielded a hidden 16-byte storage area initialized with "\016the square of \0" (don't forget that \0xx is OCTAL). So, the sprintf example above should cough up the storage area tempstring filled with "\016the square of xxxxxx is yyyyyy\0" which would draw on the screen "the square of " since the \016 would tell DrawString to use only 14 characters out of tempstring. The correct way would be to use the CtoPStr function against tempstring, forgetting the \p stuff completely (since this scenario is exactly what this function is for). The \p notation is for string literals that aren't to be massaged later by C string functions before being sent to the Toolbox. Of course, LSC might do something differently, like it could treat \p as a literal constant character that glue versions of DrawString (et. al.) could notice and then do internal CtoPStr operations (gackkk!). This is somewhat in accord with how I read the second poster's information. I don't think LSC does this though, though I don't have it available to check. I thought the manual for Aztec C was reasonably clear on the whole matter, although I don't remember it it used examples. +----------------+ ! II CCCCCC ! Jim Cathey ! II SSSSCC ! ISC Systems Corp. ! II CC ! TAF-C8; Spokane, WA 99220 ! IISSSS CC ! UUCP: uunet!iscuva!jimc ! II CCCCCC ! (509) 927-5757 +----------------+ "With excitement like this, who is needing enemas?"
rs4u+@andrew.cmu.edu (Richard Siegel) (02/04/88)
"Of course, LSC might do something differently, like it could treat \p as a literal constant character that glue versions of DrawString (et. al.) could notice and then do internal CtoPStr operations (gackkk!). This is somewhat in accord with how I read the second poster's information. I don't think LSC does this though, though I don't have it available to check." LightspeedC doesn't do this. The exact mechanism I don't know, but what happens with "\pfoo" is that you get a 4-byte space with a length byte at the beginning followed by the characters, which is suitable for passing to ROM traps. There's no glue involved. MPW and Aztec, on the other hand, allow you to pass C strings to ROM calls; they *do* have glue. For EVERY SINGLE trap that takes a string, they have glue. Icky. --Rich
tedj@hpcilzb.HP.COM (Ted Johnson) (02/04/88)
I have found a solution to my problem. To print out floats and integers in Lightspeed C, use the following: char s[256]; float x= 3.3; int y = 1; sprintf(s, "Identity number %d: %f squared = %f", x, (x * x)); /*To print this in a window...*/ DrawString(CtoPstr(s)); /*Or to print this in the "stdio window", do...*/ printf(s); BTW, I tried to do this same thing using a Str255 variable instead of a char array (in a variation of the above code), but it bombed... Also, using DrawString() *should* also work for a DA's window (after you first recompile the sprintf/scanf library as a DA, so that things are referenced off of A4 instead of A5), but it doesn't. :-( Any theories or workarounds are welcomed! -T("All I want to do is print the value of a float in a DA's window!")ed
levin@bbn.com (Joel B Levin) (02/04/88)
In article <MW1oTmy00Xo18P01No@andrew.cmu.edu> rs4u+@andrew.cmu.edu (Richard Siegel) writes:
:MPW and Aztec, on the other hand, allow you to pass C strings to ROM calls;
:they *do* have glue. For EVERY SINGLE trap that takes a string, they have
:glue.
:Icky.
As of MPW 2.0, you can avoid the glue in most cases, because two
things have been added:
1. In the #include files, for each trap where the only differences
between the "glued" version and the trap are string type and calling
sequence, a definition has been added which invokes the trap directly,
e.g.,
SetWTitle (theWindow, cString);
gets you some glue, but
SETWTITLE (theWindow, PStringPtr);
gets you the trap without glue. This doesn't work for OS calls which
don't use the stack; there you always need glue, I imagine even in LSC.
2. The compiler recognizes the "special" character \p at the head of a
string constant and translates it to a length byte, so you can now say
SETWTITLE (theWindow, "\pNew title");
I have been playing in my spare time with the problem of translating
LSC into MPW (I don't have LSC or a manual, so I'm half blind) --
specifically, TransSkel, TransDisplay, and TransEdit and their demos.
It has been most educational. Before I learned of these new features
of MPW 2.0, it was a lot of work; this has made it much easier. When
I have done, I'll probably write up the lessons I've learned so it is
easier for someone else to do this. (Unless, of course, someone has
written a translator?)
/JBL
UUCP: {harvard, husc6, etc.}!bbn!levin
ARPA: levin@bbn.com
pollock@usfvax2.UUCP (Wayne Pollock) (02/06/88)
Funny; I thought for sure it would work. I haven't tested it, but it would seem to me that the \p is interpreted in some sort of glue routine, well after the string is constructed. That is, when a string containing "\p" is passed to some toolbox routine, AT THAT TIME the length of the string is determined, and substituted for the first byte. If it works this way, then the example given would indeed work as desired. I'm not sure how it could work this way, unless LSC reserves some char code (such as 255) as a marker; of course this would be incompatible with C syntax. Anybody know for certain, or willing to crash his mac to check this out? Wayne Pollock (The MAD Scientist) pollock@usfvax2.usf.edu.UUCP Usenet: ...!{ihnp4, cbatt}!codas!usfvax2!pollock GEnie: W.POLLOCK
palmer@tybalt.caltech.edu (David Palmer) (02/09/88)
In article <943@cadre.dsl.PITTSBURGH.EDU> cgw@cadre.dsl.pittsburgh.edu.UUCP (Gray Watson) writes: >> sprintf(tempstring, "%s %f %s %f", "\pthe square of ", x, "is", (x *x)); >> DrawString(tempstring); > >Article <5349@cit-vax.Caltech.Edu> stated that the lines above "will not work >in any C which [he] understand[s]". Tempstring should, according the article >be equal to "\016the square of" followed by random garbage. > >Well I don't know what version of C you are using but the example WILL work: > > Sscanf should, like strcat, strcpy, etc. pad any string produced with >with a \0 (NULL) character. If it doesn't then it is your compiler's fault. > The \p (which for non-Mac routines does insert a \016) is needed for >the Mac interface. The first character in the string you send to DrawString >should be the value of the length of the string or should be \p or \016: I don't know whether this has been hashed to death (our news-feed has been down for a week) but you are missing the point. The string produced by "\pthe square of " is NOT null terminated (it is a Pascal string, and so the length is specified by a byte at the beginning, rather than a terminator at the end). Sprintf requires null-terminated (C) strings, and so when it is passed a pointer to a Pascal string, it assumes that the string goes on until it hits a \0, somewhere out in random memory beyond the end of the string. It is true that the string 'tempstring' will be null terminated by sprintf, but the puropose of this exercise was to get a Pascal string. If you pass 'tempstring' to a function which uses Pascal strings, it will see only the first 14 (specified by the \016 in octal) characters: "the square of " >If you are setting up a window title to be "Hello Dolly" the string you > should give the OpenWindow call (or whatever it is) should be > "\011Hello Dolly" with \011 being the length of "Hello Dolly", (^ this should be \013, because \xxx requires xxx to be in octal) > but "\pHello Dolly" saves you from recounting the length of the string > if you change it a lot. True, but the '\p' in "\pHello Dolly" is just a directive to tell the compiler to count the characters for itself, and the string is stored in memory as "\013Hello Dolly", with no null termination. > >To translate from a Mac returned string into correct C format: > >If file_name[20] is returned I do a: > file_name[file_name[0]] = 0; /* punch the string-end with a null */ > and refer to the string as &file_name[1] > >Or if you have memory and speed to burn: > If temp[20] is returned: > You can do a strncpy(file_name,&temp[1],temp[0]); > Which makes file_name be a correct C string with the returned name. Or you can use the procedures PtoCStr() and CtoPStr() which are included in most compilers. David Palmer palmer@tybalt.caltech.edu ...rutgers!cit-vax!tybalt.caltech.edu!palmer "Every day it's the same thing--variety. I want something different."
dudek@ai.toronto.edu (Gregory Dudek) (02/17/88)
Just to correct some apparent misinformation that has been propagated on this subjec... In article <5383@cit-vax.Caltech.Edu> palmer@tybalt.caltech.edu.UUCP (David Palmer) writes: >In article <943@cadre.dsl.PITTSBURGH.EDU> cgw@cadre.dsl.pittsburgh.edu.UUCP (Gray Watson) writes: >>> sprintf(tempstring, "%s %f %s %f", "\pthe square of ", x, "is", (x *x)); >>> DrawString(tempstring); [ etc, etc ] >> > >The string produced by "\pthe square of " is NOT null terminated (it is >a Pascal string, and so the length is specified by a byte at the beginning, >... >True, but the '\p' in "\pHello Dolly" is just a directive to tell the >compiler to count the characters for itself, and the string is stored in >memory as "\013Hello Dolly", with no null termination. > Aztec C produces a C-string *WITH* a null terminator when it sees: "\Pfoo". In other words it's a legal Pascal string but has an EXTRA character (null) that Pascal routines won't notice, thus making it a legal C-string also. This seems like a very sensible idea since C routines invoked on it won't blow up & things like strcpy still work. I don't know what other complers do, but I would be seem reasonable if they did the same. Of course, this doesn't solve the original poster's problem. He should use something like: sprintf(tmp,"%s %d ect",...); DrawString(CtoPascal(tmp)); where CtoPascal is appropriately defined (most compilers include a library routine that does this). As for glue routines, Aztec C uses them only for *some* ROM traps; most are defined as straight ROM entries. Greg Dudek -- Dept. of Computer Science (vision group) University of Toronto Reasonable mailers: dudek@ai.toronto.edu Other UUCP: {uunet,ihnp4,decvax,linus,pyramid, dalcs,watmath,garfield,ubc-vision,calgary}!utai!dudek ARPA: user%ai.toronto.edu@relay.cs.net