hiya guys,
saw this code, curious as to why the author -1 from the sizeof?
why wouldnt the strncpy just be the size of host??Code:char host[512] memset (&host, 0, sizeof(host)); strncpy (host, argv[optind], sizeof (host) -1 );
Cheers!
hiya guys,
saw this code, curious as to why the author -1 from the sizeof?
why wouldnt the strncpy just be the size of host??Code:char host[512] memset (&host, 0, sizeof(host)); strncpy (host, argv[optind], sizeof (host) -1 );
Cheers!
The last character wouldn't be copied.
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
> memset (&host, 0, sizeof(host));
Unnecessary & here
> why wouldnt the strncpy just be the size of host?
Well having expensively filled the array with zeros, by only copying n-1 characters you ensure there is at least one \0 in the string.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
So do you think the memset is unnesessary here?
I quite new to mem operations, i assumed it was good to sanatise the array??
So by coping one less you make sure there is one 0 at the end. Is that was \0 is?
Sorry, i understand that \0 represents the end of a string, (not sure if that the best way to put it) just didnt know how that is actually represnted. Is a 0 byte = \0 then. Im sure this probably seems very stupid! Just one of those things, self taught so im sure I always miss things I should have leant!
Thankyou! Appreciate that, clears it up. I thought it was due to some kind of security, stop buffer overflows or something!
*edit-spelling.
The memset is unecessary because it fills the entire buffer with zeroes. However, you need something to ensure there a '\0' (null character) at the end because strncpy is brain damaged. If the source is longer than the destination buffer (according to your specified size) then strncpy won't terminate the string with a null, so you need something to add a null at the end always.
strncpy's other brain damaged behaviour is to fill the rest of the buffer with nulls if the source is shorter than the destination buffer.
Not in my compiler.Originally Posted by cwr
Output:Code:#include <stdio.h> #include <string.h> int main() { char a[] = "abcdefghijklmnop"; char b[] = "1234567890"; printf("%s \n", a); strncpy(a, b, 7); printf("%s \n", a); return 0; }
Although further testing shows (this is probably what you meant):abcdefghijklmnop
1234567hijklmnop
If the source buffer is smaller than the number of characters specified, behaviour of strncpy() is to fill the extra characters in the destination buffer with '\0' until the number of characters specified is reached. IOW,
7 characters in destination are filled, with '1', '2', '3' and 4 nulls. I don't consider this brain damaged. You asked to move 7 characters. Only 3 were available. Fill the rest with \0. After all, we did specify 7...Code:char a[] = "abcdefghijklmnop"; char b[] = "123"; strncpy(a, b, 7);
Definition: Politics -- Latin, from
poly meaning many and
tics meaning blood sucking parasites
-- Tom Smothers
strncpy's other (other) brain damage is that it doesn't always append a \0.
> So do you think the memset is unnesessary here?
Well this does the same thing
strncpy (host, argv[optind], sizeof (host) -1 );
host[sizeof (host)-1] = '\0';
ISTR a website from one of the authors of C explaining the behaviour of strncpy etc. It is a relic of some very old UNIX API as I recall.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
I already stated that in my post above.Originally Posted by Salem
Yes, that's what I meant. I realise my wording was unclear, but obviously the length of the destination buffer has no effect on the behaviour of strncpy, only the specified size, since strncpy doesn't know the length of the destination buffer.Originally Posted by WaltP
I should say its use is frequently brain damaged from a performance perspective.Originally Posted by WaltP
This always writes 16383 characters no matter how long src is. character arrays rarely benefit from being zeroed out as long as we are careful that they have one null character to determine the end.Code:char x[16384]; strncpy(x, src, sizeof x - 1);
Wow, some really interesting responses. Really understand whats going on now.
Its really interesting how different people approach a subject. Salem, cheers for that sample code, that makes much more sense.
How is strncpy not copying a null over a brain damage thing? What if you are only copying part of a string into the middle of another string? Would you really want it putting a null character there?
I tried doing what Saleam suggested:
strncpy (host, argv[optind], sizeof (host) -1 );
host[sizeof (host)-1] = '\0';
However the compiler wouldnt let me. Replacing the ='\0'; with = 0; does work thought. Are they the same thing??
If you were deliberately avoiding null termination by copying part of the string, you could just use memcpy instead.Originally Posted by Thantos
It's brain damaged because you'd expect a function concerned with copying strings to always result in a string. If you consider that in C, "string" is synonymous with "null terminated character array", and strncpy violates this idea.
A lot of bad code simply has strncpy(dst, src, sizeof dst); and doesn't bother to explicitly null terminate the string. One might be tempted to say "that's the programmer's fault", and it is, but it also goes against what one expects.
edit: The C FAQ entry has more info on why strncpy was designed as it was, and also suggests memcpy and/or strncat for accomplishing similar.
Because strncpy() is the approved string copy function.Originally Posted by cwr
No you wouldn't. If you want it null terminated, use strcpy() or strcat().Originally Posted by cwr
strncpy() is meant to move substrings into other strings, not concatinate the source string into the middle of another string erasing the end.
They are either using strncpy() wrong, or correctly replacing a substring. One would not expect strncpy() to truncate the string -- by its definition/description.Originally Posted by cwr
Definition: Politics -- Latin, from
poly meaning many and
tics meaning blood sucking parasites
-- Tom Smothers
> I already stated that in my post above.
So you did - my mistake.
And thanks for the link - I'd obviously forgotten that it was in the clc FAQ.
> However the compiler wouldnt let me
Explain with an error message - how didn't it "let you" do that?
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Old New Thing: strncpy
In short, it would be a good idea to forget that strncpy exists.