Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!lll-tis!ames!nrl-cmf!cmcl2!rutgers!ucla-cs!cit-vax!tybalt.caltech.edu!palmer From: palmer@tybalt.caltech.edu (David Palmer) Newsgroups: comp.sys.mac Subject: Re: sprintf() bug? Message-ID: <5383@cit-vax.Caltech.Edu> Date: 8 Feb 88 18:24:21 GMT References: <4VzXREy00WABE7k0FU@andrew.cmu.edu> <5349@cit-vax.Caltech.Edu> <943@cadre.dsl.PITTSBURGH.EDU> Sender: news@cit-vax.Caltech.Edu Reply-To: palmer@tybalt.caltech.edu.UUCP (David Palmer) Organization: California Institute of Technology Lines: 59 Keywords: C,sprintf,strings 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."