473,407 Members | 2,359 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

sizeof(str) or sizeof(str) - 1 ?

If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
If I have a 'string' that should NOT be NULL terminated, is it good practice
to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?

Is this function bug-free?

void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */
}
Nov 14 '05 #1
11 4065

"Trevor" <tr****@spam.com> a écrit dans le message de
news:yGmbc.62053$K91.150753@attbi_s02...

Hi,
If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
If I have a 'string' that should NOT be NULL terminated, is it good practice to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?
When using strncpy, you deal with strings, perhaps much more accessed
through pointers than using arrays. In this case, sizeof isn't really
appropriate.
Why don't you use strlen instead of the sizeof operator ?
Is this function bug-free?
No, It probably crashes if name is null.
void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */


Both of these preserve the terminating null character if name is shorter
than 255 characters (including \0) and is zero-terminated.

If you don't wan't to keep the terminating null character, you'll do
someting like this :

void setname(const char * name)
{
char * buf;
/*...*/
if (name!= NULL)
{
buf = malloc(strlen(name));
strncpy(buf, name, strlen(name));
}
/*...*/
}

Regis
Nov 14 '05 #2
Mistake,
void setname(const char * name)
{
char * buf;
/*...*/
if (name!= NULL)
{
buf = malloc(strlen(name));
if (buf != NULL)
{
strncpy(buf, name, strlen(name));
}
}
/*...*/

Nov 14 '05 #3
Trevor wrote:
If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
If I have a 'string' that should NOT be NULL terminated, is it good practice
to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?

Is this function bug-free?

void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */
}


A 'string' is NUL or '\0' terminated, by definition (not NULL). A
'string' is neither a variable nor a type. You can't apply sizeof to a
'string'. So let's start over with arrays of char.

char buf[256];

...is simply space, a place that can hold 256 variables of type char.

char *name = "Hello";

Now name points to a literal string of exactly six objects of type char.
The six are 'H', 'e', 'l', 'l', 'o', '\0'.

strncpy(buf, name, sizeof buf);

This will copy the six chars of name into buf and fill the remaining 250
chars of buf with '\0'.

strncpy(buf, name, sizeof buf - 1);

This will copy the six chars of name into buf and fill 249 of the
remaining 250 chars of buf with '\0'. Hmm? I'm not clear on your
'preserve the NUL terminator' question.
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #4
On Fri, 02 Apr 2004 23:28:30 GMT, "Trevor" <tr****@spam.com> wrote:
If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
sizeof is only useful if string is in an array whose definition is in
scope (not one passed in to a function). The answer to your question
is determined by whether or not you want to copy the terminal '\0'.
If I have a 'string' that should NOT be NULL terminated, is it good practice
to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?
If it is not '\0' terminated (not NULL which is something else), then
it is not a string by definition. The value that you use for strncpy
is based solely on the number of characters you want to copy.

Is this function bug-free?

void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */
Your comments are backwards. They are also misleading. If strncpy
detects a '\0', it will copy it in either case. Neither one will
overrun the destination array so they are bug free in that sense.
}

<<Remove the del for email>>
Nov 14 '05 #5
In 'comp.lang.c', Christian Bau <ch***********@cbau.freeserve.co.uk>
wrote:
I suggest writing your own function, like

void my_strncpy (char* dst, const char* src, size_t maxlen)
{
if (strlen (src) < maxlen) {
strcpy (dst, src);
} else if (maxlen > 0) {
memcpy (dst, src, maxlen - 1);
dst [maxlen - 1] = '\0';
}
}


I think that scanning the string twice (strlen(), strcpy()) is not a good
idea. Here is my STR_safecopy() (from my personal library at
http://mapage.noos.fr/emdel)

char *STR_safecopy (char *const des
,size_t const size
,char const *const src)
{
char *s_out = NULL;
if (des && size && src)
{
memcpy (des, src, size - 1);
des[size - 1] = 0;
s_out = des;
}

return s_out;
}

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #6
Emmanuel Delahaye wrote:
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:
I suggest writing your own function, like

void my_strncpy (char* dst, const char* src, size_t maxlen)
{
if (strlen (src) < maxlen) {
strcpy (dst, src);
} else if (maxlen > 0) {
memcpy (dst, src, maxlen - 1);
dst [maxlen - 1] = '\0';
}
}


I think that scanning the string twice (strlen(), strcpy()) is not
a good idea. Here is my STR_safecopy() (from my personal library at
http://mapage.noos.fr/emdel)


You can also use a prototype that has been well tested (see
references) and, in my implementation, does not use the standard
library at all. If the names strlcpy/strlcat create any problems
change them. BSD systems, will not, I believe, need any
implementation whatsoever. This code is deliberately minimized,
for performance reasons.

Please read the reference at:
<http://www.courtesan.com/todd/papers/strlcpy.html>

/* ------- file strlcpy.h ------- */
#ifndef strlcpy_h_
#define strlcpy_h_

#ifdef __cplusplus
extern "C" {
#endif

/* Implementation of strlcpy and strlcat
See http://www.courtesan.com/todd/papers/strlcpy.html

These routines are explicitly designed to move no
data and simply return the projected size of the
final strings when called with sz == 0.

In addition they treat src == NULL as an empty string

strlcat expects that the sz parameter is greater than
the size of the dst string. If not, the treatment is
exactly the same as if a sz value of 0 was used.

NOTE: these routines are deliberately designed to
not require any assistance from the standard
libraries. This makes them more useful in any
embedded systems that must minimize the load size.

Public domain, by C.B. Falconer
bug reports to mailto:cb********@worldnet.att.net
*/

#include <stddef.h>

size_t strlcpy(char *dst, const char *src, size_t sz);
size_t strlcat(char *dst, const char *src, size_t sz);

#ifdef __cplusplus
}
#endif

#endif
/* ------- End file strlcpy.h ------- */

/* ------- file strlcpy.c ------- */
#include "strlcpy.h"

/* ---------------------- */

size_t strlcpy(char *dst, const char *src, size_t sz)
{
const char *start = src;

if (src && sz--) {
while ((*dst++ = *src))
if (sz--) src++;
else {
*(--dst) = '\0';
break;
}
}
if (src) {
while (*src++) continue;
return src - start - 1;
}
else if (sz) *dst = '\0';
return 0;
} /* strlcpy */

/* ---------------------- */

size_t strlcat(char *dst, const char *src, size_t sz)
{
char *start = dst;

while (*dst++) /* assumes sz >= strlen(dst) */
if (sz) sz--; /* i.e. well formed string */
dst--;
return dst - start + strlcpy(dst, src, sz);
} /* strlcat */

/* testing code snipped */
/* ------- End file strlcpy.c ------- */

Some comments and testing have been snipped. The unaltered files
are available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>

--
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 #7
In article <yGmbc.62053$K91.150753@attbi_s02>,
"Trevor" <tr****@spam.com> wrote:
If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
If I have a 'string' that should NOT be NULL terminated, is it good practice
to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?
Just because strncpy is in the Standard C library doesn't mean you
should use it. Its definition makes it basically useless. First, lets
say you were generous and the size of str is 10000 bytes. Every call of
strncpy (str, "Hello", 10000) will copy five characters and then set
9995 bytes to zero. What's worse, you are not guaranteed to end up with
a legitimate string. I suggest writing your own function, like

void my_strncpy (char* dst, const char* src, size_t maxlen)
{
if (strlen (src) < maxlen) {
strcpy (dst, src);
} else if (maxlen > 0) {
memcpy (dst, src, maxlen - 1);
dst [maxlen - 1] = '\0';
}
}
Is this function bug-free?

void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */
}


If strlen (name) >= 255, then null_buf will contain the first 255
characters of name, followed by an indeterminate character, so it is
highly unlikely to be a legitimate C string.

What you can do:

strncpy (buf, name, sizeof (buf));
buf [sizeof (buf) - 1] = '\0';
or
strncpy (buf, name, sizeof (buf) - 1);
buf [sizeof (buf) - 1] = '\0';
Nov 14 '05 #8
In article <c4**********@news-reader2.wanadoo.fr>,
"Régis Troadec" <re**@wanadoo.fr> wrote:
"Trevor" <tr****@spam.com> a écrit dans le message de
news:yGmbc.62053$K91.150753@attbi_s02...

Hi,
If I have a string that should be NULL terminated, is it good practice to
use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy?
If I have a 'string' that should NOT be NULL terminated, is it good

practice
to use "sizeof(str) - 1" or "sizeof(str)" when using a function like
strncpy?


When using strncpy, you deal with strings, perhaps much more accessed
through pointers than using arrays. In this case, sizeof isn't really
appropriate.
Why don't you use strlen instead of the sizeof operator ?


Because it is nonsense? To use strncpy, you must know how much space is
available to hold the result. If 1000 bytes of space are available, then
pass 1000 to strncpy. If I called strcpy (dst, "Hello") first, your idea
would mean that only the first five bytes of dst can be used. Worse yet,
it makes it impossible to copy a string to an uninitialised array.

Is this function bug-free?


No, It probably crashes if name is null.
void setname(char *name)
{
char null_buf[256];
char buf[256];
strncpy(buf, name, sizeof(buf)); /* don't preserver NULL terminator */
strncpy(null_buf, name, sizeof(buf) - 1); /* preserve NULL terminator */


Both of these preserve the terminating null character if name is shorter
than 255 characters (including \0) and is zero-terminated.

If you don't wan't to keep the terminating null character, you'll do
someting like this :

void setname(const char * name)
{
char * buf;
/*...*/
if (name!= NULL)
{
buf = malloc(strlen(name));
strncpy(buf, name, strlen(name));
}
/*...*/
}


Could you explain to us what that function would be good for? There is
no way for the caller to find out how many characters are stored in buf,
so that is useless. Oh, I noticed you forgot to return buf to the
caller... So you created a memory leak full of garbage data...
Nov 14 '05 #9

"Christian Bau" <ch***********@cbau.freeserve.co.uk> a écrit dans le message
de news:ch*********************************@slb-newsm1.svr.pol.co.uk...

Hi,
When using strncpy, you deal with strings, perhaps much more accessed
through pointers than using arrays. In this case, sizeof isn't really
appropriate.
Why don't you use strlen instead of the sizeof operator ?
Because it is nonsense? To use strncpy, you must know how much space is
available to hold the result. If 1000 bytes of space are available, then
pass 1000 to strncpy.


It's not a nonsense I think :
- How could you apply sizeof to a pointer ?
- Another common way to use strncpy() is to copy only the N first
characters of the source string in the destination string.

Sure, the main purpose of strncpy() is to provide a safer way to copy
strings than strcpy(), and I think that if you know the available space in
the destination buffer, you should directly pass it to strncpy(). In
strncpy, sizeof should be only applied to arrays whose size isn't known.

void setname(const char * name)
{
char * buf;
/*...*/
if (name!= NULL)
{
buf = malloc(strlen(name));
strncpy(buf, name, strlen(name));
}
/*...*/
}


Could you explain to us what that function would be good for?


Answering to the OP question about obtaining a not null terminated *string*.
There is no way for the caller to find out how many characters are stored in buf, so that is useless.
Sure he can: using strlen and adding another function argument.
Oh, I noticed you forgot to return buf to the
caller... So you created a memory leak full of garbage data...


But you did'nt notice my /*...*/ lines, which mean that you can have extra
code and other processings in the function, you could'nt guess. buf could
only be a local pointer to serve in many other processings in the function,
and would be of course freed as soon as it's useless.

Regis
Nov 14 '05 #10
In 'comp.lang.c', Christian Bau <ch***********@cbau.freeserve.co.uk>
wrote:
I suggest writing your own function, like

void my_strncpy (char* dst, const char* src, size_t maxlen)
{
if (strlen (src) < maxlen) {
strcpy (dst, src);
} else if (maxlen > 0) {
memcpy (dst, src, maxlen - 1);
dst [maxlen - 1] = '\0';
}
}


I think that scanning the string twice (strlen(), strcpy()) is not a good
idea. Here is my STR_safecopy() (from my personal library at
http://mapage.noos.fr/emdel)

char *STR_safecopy (char *const des
,size_t const size
,char const *const src)
{
char *s_out = NULL;
if (des && size && src)
{
memcpy (des, src, size - 1);
des[size - 1] = 0;
s_out = des;
}

return s_out;
}

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #11
Emmanuel Delahaye wrote:
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:
I suggest writing your own function, like

void my_strncpy (char* dst, const char* src, size_t maxlen)
{
if (strlen (src) < maxlen) {
strcpy (dst, src);
} else if (maxlen > 0) {
memcpy (dst, src, maxlen - 1);
dst [maxlen - 1] = '\0';
}
}


I think that scanning the string twice (strlen(), strcpy()) is not
a good idea. Here is my STR_safecopy() (from my personal library at
http://mapage.noos.fr/emdel)


You can also use a prototype that has been well tested (see
references) and, in my implementation, does not use the standard
library at all. If the names strlcpy/strlcat create any problems
change them. BSD systems, will not, I believe, need any
implementation whatsoever. This code is deliberately minimized,
for performance reasons.

Please read the reference at:
<http://www.courtesan.com/todd/papers/strlcpy.html>

/* ------- file strlcpy.h ------- */
#ifndef strlcpy_h_
#define strlcpy_h_

#ifdef __cplusplus
extern "C" {
#endif

/* Implementation of strlcpy and strlcat
See http://www.courtesan.com/todd/papers/strlcpy.html

These routines are explicitly designed to move no
data and simply return the projected size of the
final strings when called with sz == 0.

In addition they treat src == NULL as an empty string

strlcat expects that the sz parameter is greater than
the size of the dst string. If not, the treatment is
exactly the same as if a sz value of 0 was used.

NOTE: these routines are deliberately designed to
not require any assistance from the standard
libraries. This makes them more useful in any
embedded systems that must minimize the load size.

Public domain, by C.B. Falconer
bug reports to mailto:cb********@worldnet.att.net
*/

#include <stddef.h>

size_t strlcpy(char *dst, const char *src, size_t sz);
size_t strlcat(char *dst, const char *src, size_t sz);

#ifdef __cplusplus
}
#endif

#endif
/* ------- End file strlcpy.h ------- */

/* ------- file strlcpy.c ------- */
#include "strlcpy.h"

/* ---------------------- */

size_t strlcpy(char *dst, const char *src, size_t sz)
{
const char *start = src;

if (src && sz--) {
while ((*dst++ = *src))
if (sz--) src++;
else {
*(--dst) = '\0';
break;
}
}
if (src) {
while (*src++) continue;
return src - start - 1;
}
else if (sz) *dst = '\0';
return 0;
} /* strlcpy */

/* ---------------------- */

size_t strlcat(char *dst, const char *src, size_t sz)
{
char *start = dst;

while (*dst++) /* assumes sz >= strlen(dst) */
if (sz) sz--; /* i.e. well formed string */
dst--;
return dst - start + strlcpy(dst, src, sz);
} /* strlcat */

/* testing code snipped */
/* ------- End file strlcpy.c ------- */

Some comments and testing have been snipped. The unaltered files
are available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>

--
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 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Alexander Malkis | last post by:
How to recover from failing cin.get(str,n,'\n')? The user pressed "Enter" on cin.get(...).I would like to let him try once more but the system doesn't stop on the next cin.get. Code: ...
10
by: Trevor | last post by:
If I have a string that should be NULL terminated, is it good practice to use "sizeof(str)" or "sizeof(str) - 1" when using a function like strncpy? If I have a 'string' that should NOT be NULL...
83
by: rahul8143 | last post by:
hello, what is difference between sizeof("abcd") and strlen("abcd")? why both functions gives different output when applied to same string "abcd". I tried following example for that. #include...
11
by: Alfonso Morra | last post by:
Hi, I am at the end of my tether now - after spending several days trying to figure how to do this. I have finally written a simple "proof of concept" program to test serializing a structure...
9
by: electrixnow | last post by:
Can anyone tell me who sizeof &tokens only return a int of 4 no matter how many strings that are in the token. thanks, Grant #include <cstring>
4
by: goldfita | last post by:
My last post - http://groups.google.com/group/comp.lang.c/browse_thread/thread/eacc2938b4c8ee66/0bdf6ab20a6007d0 I have a little bit more challenging question this time. Suppose I have ...
15
by: junky_fellow | last post by:
Hi, Is it possible to implement sizeof as a C function ?
7
by: guoliang | last post by:
help: i try the code: " char str={'h','e','l','l','o','\n','\0'}; char *pstr=str; printf("sizeof=%d\n",sizeof(str)); printf("sizeof=%d\n",sizeof(pstr)); //i want to get sizeof(str) not...
3
by: Nope | last post by:
LO everybody, I have a string (defined as a character array), and a structure which comprises of unsigned chars, chars or char arrays. I want to copy the 'string' into the structure, in one...
6
by: Aftabpasha | last post by:
I have seen the following program. #include<stdio.h> int main() { char str="S\065AB"; printf("\n%d", sizeof(str)); return(0); }
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.