Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!helios!stat!john From: john@stat.tamu.edu (John S. Price) Newsgroups: comp.lang.c Subject: Re: strncpy Summary: So what's your point? Message-ID: <4128@helios.TAMU.EDU> Date: 24 Jan 90 01:31:33 GMT References: <11527@csli.Stanford.EDU> <000003Q@cdis-1.UUCP> <11616@csli.Stanford.EDU> <48314938.f69e@phobos.UUCP> <11864@csli.Stanford.EDU> <25BC3A32.3F5B@marob.masa.com> <11881@csli.Stanford.EDU> Sender: usenet@helios.TAMU.EDU Reply-To: john@stat.tamu.edu (John S. Price) Organization: Statistics Department, Texas A&M University Lines: 114 In article <11881@csli.Stanford.EDU> poser@csli.stanford.edu (Bill Poser) writes: > >The manual page does indeed say that strncpy(3) copies exactly >N characters, but as William Davidsen has pointed out, the manual, >at least on some systems, is wrong. Here is a little test program. > >#include >main() >{ > char src[20]; > char tgt[20]; > > sprintf(src,"%s","abcdefg"); > printf("src = %s\n",src); > src[3] = '\0'; > printf("src = %s\n",src); > strncpy(tgt,src,5); > printf("tgt = %s\n",tgt); > > exit(0); >} > >It puts the string "abcdefg" (7 characters plus a null) into src >and prints it out. Then it assigns a null to the 4th position, overwriting >the "d" and prints it out. Then it strncpy's it to tgt, requesting a 5 >character copy, and prints the result. I just compiled and ran this program >on: (a) a SUN 4 running SUN-OS; (b) an HP 9000/350 running HP-UX, and >(c) an HP 9000/320 running 4.3 Tahoe BSD. On all three the result was that >the null byte terminated the copy. Here is the script from the HP 350: > >Script started on Tue Jan 23 14:58:27 1990 >crystals-[1]/user2/poser >: foo >src = abcdefg >src = abc >tgt = abc >crystals-[2]/user2/poser >: >script done on Tue Jan 23 14:58:33 1990 > >If strncpy copied exactly N characters, the third output line should >read: tgt = abcde >On all three systems the manual says that strncpy copies exactly N >characters, and on all three it is wrong. Every manual I read says this: "... If the string pointed to by the source has fewer than count characters, nulls are added to the end of dest until count characters have been copied." -- C - The Complete Reference. "... strncpy(s,t,n) copy exactly n characters; null pad if necessary" -- Unix Programming Environment The key to this is the way C, or for that matter, ASCIIZ, string convention works. A series of characters followed by a NULL is considered a string. So, if you have a string foo[] = "This is a test of the Emergency Broadcast System."; and say foo[14] = NULL; You are CHANGING THE STRING LENGTH. It is now 14 characters long, instead of 49. back to the example in question... The only was strncpy can know if the source has fewer than count (in the program example 5) characters is if it's null terminated or not. So, when you say src[3]=0; you, by definition of the ASCIIZ convention, have shortened the string to 3 characters, namely "abc". When strncpy(tgt,src,5) gets a pointer to "abc\000efg" for the source, all it considers to be the STRING is "abc" and that is all it copies to tgt. It pads tgt with NULLs up to N, the number of characters specified to copy. You have to remember that all of these are STRING FUNCTIONS, not block memory move functions. If you wanted to copy the 5 bytes from src to tgt, do memcpy(tgt,src,5); But, printf would still print out "abc" for tgt, because it is NULL terminated. Only difference is that tgt[4]=='e' now, instead of NULL. strncpy() is acting exactly to the manuals specs. When it says is will copy EXACTLY 5 characters from the STRING src to the destination STRING tgt, it copys 5 characters from the string. Since strings are NULL terminated, strncpy has to assume that anything after the NULL is garbage, and not part of the string. It assumes that tgt will have N bytes allocated to it, but doesn't assume that src has at least N bytes. If src is larger than N, then it copys N characters to tgt. It doesn't NULL terminate tgt because it can't assume that tgt is N+1 bytes long. Just to clear things up... -------------------------------------------------------------------------- John Price | It infuriates me to be wrong john@stat.tamu.edu | when I know I'm right.... --------------------------------------------------------------------------