William Chops Westfield wrote: > void mystrncpy(char *op, const char *ip, const int ncharmax) > { > int n = 0; > while ((*ip != '\0') && (n++ < ncharmax)) > *op++ = *ip++; > } > > (Walks off mumbling about being bitten by corrupted strings TOO > often...) > > Um. Those terminating nulls are important (this came up quite recently, > thanks to a jihad to eliminate all non-counted string copies.) How about: Whaddya want, perfection from me for 12:40am, free code, guys? That was a quick first hack, not a copy of my source code "A jihad to eliminate all non-counted string copies." I *LIKE* it > void mystrncpy(char *op, const char *ip, const int ncharmax) > { > char c; > int n = 0; > do { > *op = *ip++; > if (++n >= ncharmax) > *op = '\0'; > } while (*op++ != '\0'); > } Reason for why I do it my way: I call strncpy with something like strncpy(output, input, sizeof(output)) - I'd limit it to the size of the output buffer, as over-running THAT, is the BAD BAD BAD thing we're trying to prevent here; Don't CARE if there's a missing null on display, so long as there's no strcpy overwriting the rest of the program's variables (I once "inherited" a bunch of old CP/M BBS code that'd been semi-reworked into Dos BBS code partially, but, about 18000 buffer size changes happened along the way, there were an embarrasment of different programmers and semi-programmers hacking on the code, you would NOT have liked what I started off with...) Good point, my 'real' strncpy() function throws a null in at output[sizeof(output) -1], though, which IS important "in real life" (It was pretty cute seeing how much better some code ran when you made buffers 4k long instead of 128 bytes or 256 bytes, size of a CP/M FDD sector was the size they'd been set to... That code had PROBLEMS, ended up darn stable.) Add to that some other pointer math done by someone who couldn't DO pointers right AFAICT, and we originally had very "interesting" behavior of the code... (Redid that in a lot simpler manner.) > I wonder at what point one should just do: > > faster_strncopy (op, ip, max) > { > memcpy(op, ip, max); > *(op+max-1) = '\0'; > } > > On short strings, the missing test instructions oughta just about balance > out any extra bytes that you copy. On longer strings, you save more test > instructions, AND you might get highly optimized behavior out of memcpy > (word moves on machines with large words, unrolled loops, all sorts of > nasty stuff.) Works for me I'm a totalitarian "functionalist" - It's gotta work right, first and foremost, the rest's window dressing Shooting ones' self in the foot isn't functional, so I've learned to use the limited versions of all string operations as much as possible (either that or use a function that returns True if it found a Nul and False otherwise, then spew out an error number and ask the user to call me, the more important things to not have the darn thing "break"! ) > BillW Mark rleggitt@CONCENTRIC.NET wrote: > > Or mebbe: > > void mystrncpy(char *op, const char *ip, int ncharmax) > { > while (--ncharmax) if (!(*op++=*ip++)) return; > *op = 0; > } Works, though maybe BillW's version IS better - I can type a working algorithm in off the top of my head, the first draft isn't always "optimal", but it'll be functional That'n I don't always use pointers as much as some, I find if you have a headache or are stressed that can really be a bit much for some days - I tend to use local variables and so on for the same reason - some bosses simply cannot DEAL with modifying a function parameter as you're doing there (I'd maybe CONST that puppy?) Mark