By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 783 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

Why strncpy(s, t, n) doesn't put '\0' at the end?

P: n/a
mZ
I am a C programming beginner...
I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string.
Because when I output the copied string, it output more than what I want,
until I put '\0' at the end by myself.

But, sometime I don't need put '\0' and it work well??
Like
strncpy(s, t, n);
strcat(s, t1);
.....
work just what I want.

Nov 14 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
"*mZ" <to****@world.com> wrote in message
news:bu**********@news.seed.net.tw...
I am a C programming beginner...
I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string.
Because when I output the copied string, it output more than what I want,
until I put '\0' at the end by myself.

But, sometime I don't need put '\0' and it work well??
Like
strncpy(s, t, n);
strcat(s, t1);
....
work just what I want.


It depends on how long the source string is. strncpy() copies up to n
characters from t into s. If t is shorter than n characters, remaining
characters in s are filled with zeros. If t is n characters long or longer,
the first n characters are copied and that's it. All of this is explained in
our manual. Have you read it first?

Peter
Nov 14 '05 #2

P: n/a

"*mZ" <to****@world.com> wrote in message
news:bu**********@news.seed.net.tw...
I am a C programming beginner...
I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string.
Because when I output the copied string, it output more than what I want,
until I put '\0' at the end by myself.

But, sometime I don't need put '\0' and it work well??
Like
strncpy(s, t, n);
strcat(s, t1);
....
work just what I want.


Thats just the way it works. If count is less than the length of the
source string then you must null terminate yourself with:

dest_str[count]='\0';

If count is greater than the length of the source string then the
destination string will be padded with 0s up to count. But you can still
do the dest_str[count]='\0' (it is just redundant in this case).

strncpy() is useful for ensuring that you never exceed the length of a
string (causing a crash), and you should always use it if the source string
could be longer than the destination string (or if you are not sure). If
the source string was longer then the destination string will not be
automatically null terminated so you should put a '\0' at the end yourself
as follows:

strncpy(dest_str,source_str,MAX_LEN_OF_DEST_STR);
dest_str[MAX_LEN_OF_DEST_STR]='\0';

If the source string was shorter that the destination string, the dest str
will already be NULL terminated and the second line will be redudant (but so
what!).

NOTE that _memccpy(dest,source,0,count) is equivalent to
strncpy(dest,source,count) but is generally much faster (at least on a
Windows platform compiling with Borland or Microsoft compilers).

Hope this helps...

Sean

Nov 14 '05 #3

P: n/a
"*mZ" <to****@world.com> wrote:
I am a C programming beginner...
I wonder, why strncpy(s, t, n) does not put '\0' at the end of the string.
Historical reasons. Originally, strncpy() was intended to work with a
particular kind of fixed length, null-padded, not necessarily null-
terminated char array, not with ordinary C strings at all.
Because when I output the copied string, it output more than what I want,
until I put '\0' at the end by myself.

But, sometime I don't need put '\0' and it work well??


What strncpy() does is copy as much of the source into the destination
as required, but if the source is smaller than the limit, pad the rest
with null characters. That means, of course, that the result will happen
to be null-terminated as well; but it's also quite likely that it will
have written more nulls than necessary.

It's often better to use strncat() instead of strncpy(), if only for
efficiency; instead of

strncpy(dest, src, n);
dest[n]='\0';

you can use

*dest='\0';
strncat(dest, src, n);

which will _also_ result in at most n characters, null-terminated, being
written to dest, but will not have written all those extra null
characters if src is short.

Richard
Nov 14 '05 #4

P: n/a
Richard Bos wrote:
"*mZ" <to****@world.com> wrote:
I am a C programming beginner...
I wonder, why strncpy(s, t, n) does not put '\0' at the end of

the string.

Historical reasons. Originally, strncpy() was intended to work with
a particular kind of fixed length, null-padded, not necessarily
null-terminated char array, not with ordinary C strings at all.
Because when I output the copied string, it output more than what
I want, until I put '\0' at the end by myself.

But, sometime I don't need put '\0' and it work well??


What strncpy() does is copy as much of the source into the destination
as required, but if the source is smaller than the limit, pad the rest
with null characters. That means, of course, that the result will
happen to be null-terminated as well; but it's also quite likely that
it will have written more nulls than necessary.


Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';

You could encapsulate this in a macro. What it costs is the time
spent to nul fill the destination on each call.

#define STRNCPY(dst, src, n) \
do {strncpy((dst), (src), (n)-1); dst[(n)] = '\0';} while (0)

and dst and n expressions should not have side effects.

A better solution IMO is to use strlcpy and strlcat, which are NOT
standard. You can find an implementation on my pages, download
section.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #5

P: n/a
"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';


ITYM
strncpy(dst, src, n); dst[n-1] = '\0'; /* copies one char too many */
or
strncpy(dst, src, n); dst[n] = '\0'; /* or n-1, depending on n */

IMO,
strncpy(dst, src, n)[n] = '\0';
is better. It's even syntactically safe.
Nov 14 '05 #6

P: n/a
Peter Pichler wrote:

"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';


ITYM
strncpy(dst, src, n); dst[n-1] = '\0'; /* copies one char too many */
or
strncpy(dst, src, n); dst[n] = '\0'; /* or n-1, depending on n */

IMO,
strncpy(dst, src, n)[n] = '\0';
is better. It's even syntactically safe.


Not so. Given the array dst[10] the element dst[10] does not exist.
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #7

P: n/a
Peter Pichler wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';
ITYM
strncpy(dst, src, n); dst[n-1] = '\0'; /* copies one char too many */
or
strncpy(dst, src, n); dst[n] = '\0'; /* or n-1, depending on n */


You have at least a point or two. Mea sloppy. Note to self:
check boundary conditions.

IMO,
strncpy(dst, src, n)[n] = '\0';
is better. It's even syntactically safe.


Hey, that's sorta cute. Obfuscated, but cute. Maybe even:

*(n + strncpy(dst, src, n)) = 0;
or
n[strncpy(dst, src, n)] = 0;
or
/* for dst of type array, not char * */
/* This one may actually have some use !! */
#define STRZCPY(dst, src) /
(((sizeof dst)-1)[strncpy(dst, src, sizeof dst)] = 0);

(WARN: newbies should not listen to this obscure maundering)

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #8

P: n/a
CBFalconer <cb********@yahoo.com> wrote in message news:<40***************@yahoo.com>...
Peter Pichler wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';


ITYM
strncpy(dst, src, n); dst[n-1] = '\0'; /* copies one char too many */
or
strncpy(dst, src, n); dst[n] = '\0'; /* or n-1, depending on n */


You have at least a point or two. Mea sloppy. Note to self:
check boundary conditions.

IMO,
strncpy(dst, src, n)[n] = '\0';
is better. It's even syntactically safe.


Great!, How about

#define STRNCPY(dst, src, n) (strncpy(dst, src, n)[n] = 0, dst)

?

- Satyajit Rai
Nov 14 '05 #9

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
Richard Bos wrote:
"*mZ" <to****@world.com> wrote:

What strncpy() does is copy as much of the source into the destination
as required, but if the source is smaller than the limit, pad the rest
with null characters. That means, of course, that the result will
happen to be null-terminated as well; but it's also quite likely that
it will have written more nulls than necessary.
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';

You could encapsulate this in a macro. What it costs is the time
spent to nul fill the destination on each call.


Well, yes. That's why. On a single call that may seem trivial, but the
total cost of a lot of strncpy() calls can be significant.
#define STRNCPY(dst, src, n) \
do {strncpy((dst), (src), (n)-1); dst[(n)] = '\0';} while (0)

and dst and n expressions should not have side effects.

A better solution IMO is to use strlcpy and strlcat, which are NOT
standard.


Why use a non-Standard solution when

dest[0]='\0'; strncat(dest, src, n);

works just as well?

Richard
Nov 14 '05 #10

P: n/a
"Joe Wright" <jo********@earthlink.net> wrote in message
news:40***********@earthlink.net...
Peter Pichler wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
Why not simply write:

strncpy(dst, src, n-1); dst[n] = '\0';
ITYM
strncpy(dst, src, n); dst[n-1] = '\0'; /* copies one char too many */ or
strncpy(dst, src, n); dst[n] = '\0'; /* or n-1, depending on n

*/
Not so. Given the array dst[10] the element dst[10] does not exist.


In that case, n == 9. That's why I said, "depending on n".
Nov 14 '05 #11

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
Richard Bos wrote:
Why use a non-Standard solution when

dest[0]='\0'; strncat(dest, src, n);

works just as well?
Because you have to pay peculiar attention to the value of n,


Peculiar? What's so unusual about having to know the length of the
memory area you're copying into? You _have_ to pass this length, or else
you're back with plain strcpy().
and the result doesn't tell you when something has been truncated.


That isn't always something you care about; and in any case, the
original strncpy() call doesn't give you that information, either.

Richard
Nov 14 '05 #12

P: n/a
Richard Bos wrote:

CBFalconer <cb********@yahoo.com> wrote:
Richard Bos wrote:
Why use a non-Standard solution when

dest[0]='\0'; strncat(dest, src, n);

works just as well?


Because you have to pay peculiar attention to the value of n,


Peculiar? What's so unusual about having to know the length of the
memory area you're copying into? You _have_ to pass this length, or else
you're back with plain strcpy().
and the result doesn't tell you when something has been truncated.


That isn't always something you care about; and in any case, the
original strncpy() call doesn't give you that information, either.


Then go right ahead and use it. I really don't mind. I don't
want to have to think about things, so the more natural the
parameters are the better. The more info I get back the better,
as long as it isn't misleading info.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.