473,587 Members | 2,496 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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_bu f, name, sizeof(buf) - 1); /* preserve NULL terminator */
}
Nov 14 '05 #1
11 4092

"Trevor" <tr****@spam.co m> a écrit dans le message de
news:yGmbc.6205 3$K91.150753@at tbi_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_bu f, 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(n ame));
strncpy(buf, name, strlen(name));
}
/*...*/
}

Regis
Nov 14 '05 #2
Mistake,
void setname(const char * name)
{
char * buf;
/*...*/
if (name!= NULL)
{
buf = malloc(strlen(n ame));
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_bu f, 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.co m> 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_bu f, 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**********@no os.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.c om/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********@yah oo.com) (cb********@wor ldnet.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$K9 1.150753@attbi_ s02>,
"Trevor" <tr****@spam.co m> 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_bu f, 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**********@n ews-reader2.wanadoo .fr>,
"Régis Troadec" <re**@wanadoo.f r> wrote:
"Trevor" <tr****@spam.co m> a écrit dans le message de
news:yGmbc.6205 3$K91.150753@at tbi_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_bu f, 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(n ame));
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(n ame));
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

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

Similar topics

5
2244
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: cin.get(str,n,'\n'); cout<<"haha\n"; char c; /* Now get '\n'. Doesn't work if the first time nothing else was input. Have this line or leave it -it doesn't...
10
394
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 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...
83
15566
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 <stdio.h> #include <string.h> void main() { char *str1="abcd";
11
2025
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 containing pointers into a "flattened" bit stream. Here is my code (it dosen't work). I would be grateful for any feedback that helps fix this. My...
9
1885
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
3750
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 write_cmd(struct ast_connection *conn, char *msg, ...); I want to call it like (forgive the syntax)
15
3265
by: junky_fellow | last post by:
Hi, Is it possible to implement sizeof as a C function ?
7
2365
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 sizeof(void *)
3
6795
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 action, using memcpy Am I correct in assuming that I can't (or shouldn't) because of structure padding? Lets say I've got a struct of {
6
3821
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
7923
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8216
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8221
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5395
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3845
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3882
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2364
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1455
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1192
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.