Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #93090 > unrolled thread
| Started by | will hunt <glovepm@gmail.com> |
|---|---|
| First post | 2016-09-01 18:50 -0700 |
| Last post | 2016-09-14 00:24 +0000 |
| Articles | 20 on this page of 76 — 21 participants |
Back to article view | Back to comp.lang.c
How to copy a string safely and efficiently in C? will hunt <glovepm@gmail.com> - 2016-09-01 18:50 -0700
Re: How to copy a string safely and efficiently in C? John Gordon <gordon@panix.com> - 2016-09-02 01:58 +0000
Re: How to copy a string safely and efficiently in C? will hunt <glovepm@gmail.com> - 2016-09-01 19:40 -0700
Re: How to copy a string safely and efficiently in C? Geoff <geoff@invalid.invalid> - 2016-09-01 20:29 -0700
Re: How to copy a string safely and efficiently in C? James Kuyper <jameskuyper@verizon.net> - 2016-09-02 12:29 -0400
Re: How to copy a string safely and efficiently in C? asetofsymbols@gmail.com - 2016-09-12 13:09 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-12 15:30 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-01 23:08 -0700
Re: How to copy a string safely and efficiently in C? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-04 23:59 -0700
Re: How to copy a string safely and efficiently in C? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-09-01 21:12 -0600
Re: How to copy a string safely and efficiently in C? <william@wilbur.25thandClement.com> - 2016-09-01 22:12 -0700
Re: How to copy a string safely and efficiently in C? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-01 23:58 -0700
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-02 10:42 +0100
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-04 22:23 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-04 23:20 -0700
Re: How to copy a string safely and efficiently in C? mark.bluemel@gmail.com - 2016-09-05 01:03 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-05 01:46 -0700
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-05 10:30 +0100
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-10 11:25 -0700
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-11 06:23 -0700
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-11 15:41 -0700
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-11 23:40 -0700
Re: How to copy a string safely and efficiently in C? Ian Collins <ian-news@hotmail.com> - 2016-09-12 21:04 +1200
Re: How to copy a string safely and efficiently in C? Melzzzzz <Melzzzzz@zzzzz.com> - 2016-09-12 09:21 +0000
Re: How to copy a string safely and efficiently in C? Ian Collins <ian-news@hotmail.com> - 2016-09-12 21:33 +1200
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-12 10:41 +0100
Re: How to copy a string safely and efficiently in C? Melzzzzz <Melzzzzz@zzzzz.com> - 2016-09-12 10:48 +0000
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-12 07:04 -0700
Re: How to copy a string safely and efficiently in C? Richard Heathfield <rjh@cpax.org.uk> - 2016-09-02 12:36 +0100
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-02 14:24 +0100
Re: How to copy a string safely and efficiently in C? Richard Heathfield <rjh@cpax.org.uk> - 2016-09-02 14:51 +0100
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-04 23:42 -0700
Re: How to copy a string safely and efficiently in C? Richard Heathfield <rjh@cpax.org.uk> - 2016-09-02 18:05 +0100
Re: How to copy a string safely and efficiently in C? Ike Naar <ike@iceland.freeshell.org> - 2016-09-02 19:48 +0000
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 01:45 +0000
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-13 11:06 +0100
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 14:09 +0000
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-13 15:30 +0100
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 14:52 +0000
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 14:54 +0000
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-13 17:18 +0100
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 18:15 +0000
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 20:30 -0700
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-15 14:03 +0000
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 12:32 -0700
Re: How to copy a string safely and efficiently in C? luser droog <luser.droog@gmail.com> - 2016-09-15 12:45 -0700
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-15 13:00 -0700
Re: How to copy a string safely and efficiently in C? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-09-15 14:52 -0600
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-15 16:04 -0700
Re: How to copy a string safely and efficiently in C? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-09-15 15:52 -0600
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-15 17:07 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-15 15:53 -0700
Re: How to copy a string safely and efficiently in C? Richard Heathfield <rjh@cpax.org.uk> - 2016-09-15 22:17 +0100
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-15 17:01 -0700
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-15 16:36 -0700
Re: How to copy a string safely and efficiently in C? Keith Thompson <kst-u@mib.org> - 2016-09-15 19:19 -0700
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-15 21:39 -0700
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-16 06:17 -0700
Re: How to copy a string safely and efficiently in C? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-16 07:04 -0700
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-16 09:11 -0700
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 22:24 -0700
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-19 15:15 +0000
Re: How to copy a string safely and efficiently in C? Richard Damon <Richard@Damon-Family.org> - 2016-09-13 08:19 -0400
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 14:07 +0000
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-13 07:57 -0700
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-13 17:33 +0100
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 18:13 +0000
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-13 11:30 -0700
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 20:03 +0000
Re: How to copy a string safely and efficiently in C? supercat@casperkitty.com - 2016-09-13 13:38 -0700
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-13 21:39 +0000
Re: How to copy a string safely and efficiently in C? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-13 23:26 +0100
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 16:14 -0700
Re: How to copy a string safely and efficiently in C? BartC <bc@freeuk.com> - 2016-09-13 15:59 +0100
Re: How to copy a string safely and efficiently in C? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 16:07 -0700
Re: How to copy a string safely and efficiently in C? cross@spitfire.i.gajendra.net (Dan Cross) - 2016-09-14 00:24 +0000
Page 1 of 4 [1] 2 3 4 Next page →
| From | will hunt <glovepm@gmail.com> |
|---|---|
| Date | 2016-09-01 18:50 -0700 |
| Subject | How to copy a string safely and efficiently in C? |
| Message-ID | <0b30b0cc-f7c5-4928-8acb-56bf2364797b@googlegroups.com> |
should I use strncpy or snprintf, and why?
[toc] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2016-09-02 01:58 +0000 |
| Message-ID | <nqamcf$fni$1@reader2.panix.com> |
| In reply to | #93090 |
In <0b30b0cc-f7c5-4928-8acb-56bf2364797b@googlegroups.com> will hunt <glovepm@gmail.com> writes:
> should I use strncpy or snprintf, and why?
It seems like strncpy() would be the obvious choice. snprintf() is
meant for assembling an output string from one or more component
parts, which doesn't seem like what you want.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | will hunt <glovepm@gmail.com> |
|---|---|
| Date | 2016-09-01 19:40 -0700 |
| Message-ID | <196b9bd0-5b80-4194-9704-014dd19ff6c2@googlegroups.com> |
| In reply to | #93091 |
On Friday, September 2, 2016 at 9:58:46 AM UTC+8, John Gordon wrote: > In <0b30b0cc-f7c5-4928-8acb-56bf2364797b@googlegroups.com> will hunt <glovepm@gmail.com> writes: > > > should I use strncpy or snprintf, and why? > > It seems like strncpy() would be the obvious choice. snprintf() is > meant for assembling an output string from one or more component > parts, which doesn't seem like what you want. > for copying a sting into a given size buffer, char dst[size]; strncpy(dst, src, size); snprintf(dst, size,"%s", src); which is better?
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2016-09-01 20:29 -0700 |
| Message-ID | <2crhsb5pobk1sgs1eghr10juhlhru14a1k@4ax.com> |
| In reply to | #93094 |
On Thu, 1 Sep 2016 19:40:24 -0700 (PDT), will hunt <glovepm@gmail.com>
wrote:
>
>for copying a sting into a given size buffer,
char src[] = "ABC";
This is an error:
>char dst[size];
The size of the array must be a constant at compile time.
For example:
char dst[20];
assert(sizeof dst >= sizeof src);
>strncpy(dst, src, size);
Better to write
strncpy(dst, src, sizeof dst);
Why?
Because if you change the size of dst, you don't have to rewrite the
call to strncpy.
You could also write:
size_t size = sizeof dst;
strncpy(dst, src, size);
But this is redundant.
Be aware, the strncpy function copies the initial count characters of
src to dst and returns dst. If count is less than or equal to the
length of src, a nul character is not appended automatically to the
copied string. If count is greater than the length of src, the
destination string is padded with nul characters up to length count.
>snprintf(dst, size,"%s", src);
Better to write:
snprintf(dst, sizeof dst, "%s", src);
Same reason as above.
Note:
The snprintf function formats and stores count or fewer characters in
buffer, and appends a terminating null character if the formatted
string length is strictly less than count characters.
You have to ensure that dst is large enough to receive the formatted
string that results from the function call.
>which is better?
That depends entirely on context.
#include <stdio.h>
#include <string.h>
#include <assert.h>
const char src[] = "ABC";
int main(void)
{
char dst[10];
assert(sizeof dst >= sizeof src);
strncpy(dst, src, sizeof dst);
snprintf(dst, sizeof dst, "%s", src);
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2016-09-02 12:29 -0400 |
| Message-ID | <nqc9d2$li5$1@dont-email.me> |
| In reply to | #93096 |
On 09/01/2016 11:29 PM, Geoff wrote: > On Thu, 1 Sep 2016 19:40:24 -0700 (PDT), will hunt <glovepm@gmail.com> > wrote: [Snipped text restored:] >> char dst[size]; >> strncpy(dst, src, size); >> snprintf(dst, size,"%s", src); ... > This is an error: >> char dst[size]; > The size of the array must be a constant at compile time. Such a declaration defines a variable length array (VLA). VLAs were not standardized until C99, and since C2011, If __STDC_NO_VLA__ is pre#defined by the implementation, VLAs will not be supported (6.10.8.3p1). VLAs can only have block scope or function prototype scope (6.7.6.2p1), no linkage, and must not have static or thread storage duration (6.7.6.2p2). However, the context of this code example was not given in sufficient detail to prohibit a VLA for any of those reasons. Taken literally, the example code had the declaration of dst immediately followed by function calls, which implies block scope. Therefore, since that declaration didn't use the static, extern or _Thread_local key words, dst has no linkage and automatic storage duration. The fact that it was written at all implies that the intended target supported VLAs.
[toc] | [prev] | [next] | [standalone]
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2016-09-12 13:09 -0700 |
| Message-ID | <39a5dfd7-a7d3-482f-ada2-c3ec7c3224b5@googlegroups.com> |
| In reply to | #93094 |
______ for copying a sting into a given size buffer, char dst[size]; strncpy(dst, src, size); snprintf(dst, size,"%s", src); which is better? -----+++ for(i=0; i<size&&(dst[i]=src[i]) ++i) ; if(i>=size) return -1; If the src and destination point to the same array memmove but i not remember args...
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-09-12 15:30 -0700 |
| Message-ID | <ln37l47nug.fsf@kst-u.example.com> |
| In reply to | #93398 |
asetofsymbols@gmail.com writes:
> ______
> for copying a sting into a given size buffer,
> char dst[size];
> strncpy(dst, src, size);
> snprintf(dst, size,"%s", src);
> which is better?
> -----+++
> for(i=0; i<size&&(dst[i]=src[i]) ++i) ;
> if(i>=size) return -1;
>
> If the src and destination point
> to the same array memmove
> but i not remember args...
Please learn to quote properly. (Your newsreader should handle this for
you.)
This part of your followup:
> for copying a sting into a given size buffer,
> char dst[size];
> strncpy(dst, src, size);
> snprintf(dst, size,"%s", src);
> which is better?
was written by will hunt on September 1.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-09-01 23:08 -0700 |
| Message-ID | <lninueal5q.fsf@kst-u.example.com> |
| In reply to | #93091 |
John Gordon <gordon@panix.com> writes:
> In <0b30b0cc-f7c5-4928-8acb-56bf2364797b@googlegroups.com> will hunt <glovepm@gmail.com> writes:
>
>> should I use strncpy or snprintf, and why?
>
> It seems like strncpy() would be the obvious choice. snprintf() is
> meant for assembling an output string from one or more component
> parts, which doesn't seem like what you want.
Yes, strncpy() is the obvious choice. It's also, most of the time, the
*wrong* choice.
I've written about strncpy() at some length here:
https://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html
To summarize: The name implies that strncpy() is to strcpy() as
strncat() is to strcat(), i.e., that it's a "safer" version that will
not write past the end of the target array (as long as you correct
tell it how big the target array is). The name is misleading.
In a very real sense, strncpy() isn't really a string function.
If the target array isn't big enough, it will not be null-terminated,
meaning that it will not contain a string. Any further attempt to
treat it as a string can fail in arbitrarily bad ways. (It also
pads the target with nulls when it *is* big enough, but that's just
a very minor inefficiency.)
This:
target[0] = '\0';
strncat(target, src, sizeof target);
is very close to what strncpy() probably *would* do if it really
were a "safer" strcpy().
But even that provides what may be only a false sense of security.
The fact that you're considering using strncpy or snprintf rather than
strcpy means that you're at least thinking about avoiding overflowing
the target array. That's a very good thing. But simply avoiding a
buffer overflow may not be enough. You should ask yourself, if the
target array isn't big enough to hold a copy of the source, *what should
I do*? If you use strncat() or snprintf(), that question is already
answered for you: the copy quietly truncates your data.
Maybe that's what you want. But imagine, for example, that you're
copying a Unix command string:
"rm -rf /home/username/unimportant_directory"
And suppose the target only has enough room to hold:
"rm -rf /home/username"
and you then pass it to system(). (If you're not familiar with
Unix-like systems, the latter will attempt to remove your entire
home directory.)
Only you can decide, in the context of your program, what should
happen if a target array isn't big enough. Sometimes quiet
truncation is the right choice, sometimes you can try to use a bigger
array, and sometimes you'd be better off terminating the program
with a fatal error message rather than continuing to operate on
incomplete data.
snprintf() has the advantage that it returns the number of
characters it *would* have copied if there were enough room, so
you can detect truncation. (You still have to remember to check,
and to decide how to handle it.) snprintf() was added in C99,
and in the past Microsoft's implementation didn't support it
well; I don't think that's a problem these days, but check your
implementation's documentation.
To summarize: Programming is hard.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-09-04 23:59 -0700 |
| Message-ID | <bc147262-68e8-467c-8b1a-4e220fc9fd99@googlegroups.com> |
| In reply to | #93091 |
On Friday, September 2, 2016 at 2:58:46 AM UTC+1, John Gordon wrote: > In <0b30b0cc-f7c5-4928-8acb-56bf2364797b@googlegroups.com> will hunt <glovepm@gmail.com> writes: > > > should I use strncpy or snprintf, and why? > > It seems like strncpy() would be the obvious choice. snprintf() is > meant for assembling an output string from one or more component > parts, which doesn't seem like what you want. > Please read other replies before responding. The advice sounds sensible, and it's a mistake anyone could make. But as others have pointed out, it's quite wrong.
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2016-09-01 21:12 -0600 |
| Message-ID | <1bvayf6lmj.fsf@pfeifferfamily.net> |
| In reply to | #93090 |
will hunt <glovepm@gmail.com> writes: > should I use strncpy or snprintf, and why? In spite of its name, strncpy() isn't a good general purpose routine like (for instance) strncat(). It copies exactly n bytes (even if the input string is shorter) and doesn't necessarily null-terminate (if the input string is longer). I sort of like dst[0] = '\0'; strncat(dst, src, n-1); Does what you most likely intended strncpy() to do, and if you don't know the length of the source string in advance it's hard to imagine a significantly more efficient implementation. If I were strictly limited to the choices in your question I'd probably use snprintf(), since that would give me a result that didn't have extra random bytes appended to my string by accident. If I were limited to the two functions, but could put some extra code in, I'd probably use strncpy(dst, src, n); dst[n-1] = '\0'; since that would be safe and would probably be faster than the extra code needed to parse the format string in snprintf() unless the string were *really* long. (just last week I was bitten by passing the result of feeding an array generated to xxd to a routine expecting a null-terminated string....). -- "Erwin, have you seen the cat?" -- Mrs. Shrödinger
[toc] | [prev] | [next] | [standalone]
| From | <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2016-09-01 22:12 -0700 |
| Message-ID | <gben9d-a4t.ln1@wilbur.25thandClement.com> |
| In reply to | #93095 |
Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote: > will hunt <glovepm@gmail.com> writes: > >> should I use strncpy or snprintf, and why? > > In spite of its name, strncpy() isn't a good general purpose routine like > (for instance) strncat(). It copies exactly n bytes (even if the input > string is shorter) and doesn't necessarily null-terminate (if the input > string is longer). > > I sort of like > > dst[0] = '\0'; > strncat(dst, src, n-1); > > Does what you most likely intended strncpy() to do, and if you don't > know the length of the source string in advance it's hard to imagine a > significantly more efficient implementation. > > If I were strictly limited to the choices in your question I'd probably > use snprintf(), since that would give me a result that didn't have extra > random bytes appended to my string by accident. > > If I were limited to the two functions, but could put some extra code > in, I'd probably use > > strncpy(dst, src, n); > dst[n-1] = '\0'; > > since that would be safe and would probably be faster than the extra > code needed to parse the format string in snprintf() unless the string > were *really* long. > > (just last week I was bitten by passing the result of feeding an array > generated to xxd to a routine expecting a null-terminated string....). It may have changed since last time I checked, but the implementation of snprintf in glibc could fail on allocation failure. It uses the same internals as vfprintf, must allocate (at least once per thread) a special FILE-like object, and deeper down the implementation wasn't shy about dynamically allocating various temporaries so that even a simple format specifier like "%s" could fail. Things may have improved since then. And most people never cared to begin with, or [wrongly] assumed allocation failure wasn't possible on Linux. But because of that I avoided using snprintf, as failure-proof code is much easier to work with. Those details also made glibc's snprintf totally unsafe for use from signal handlers. OpenBSD's snprintf is async-signal-safe, at least for anything not formatting floats, and even that may have been fixed. OpenBSD has strlcpy, anyhow, but it's nice when an implementation makes misuse difficult.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-09-01 23:58 -0700 |
| Message-ID | <31bf7ead-3193-44cb-859f-34eb66916a0b@googlegroups.com> |
| In reply to | #93090 |
On Friday, September 2, 2016 at 2:50:37 AM UTC+1, will hunt wrote: > > should I use strncpy or snprintf, and why? > As others have said, strncpy() is a trap (it is designed for databases with fixed string fields instead of nul-terminated strings, and is a sort of historical hangover). if( snprintf(out, N, "%s", str) >= N) /* error */; is safe. Be use to use %s in case the string contains % characters. Because C has undefined behaviour, a lot of people think that they can make programs correct by removing the undefined behaviour. Whilst that is an important first step, it doesn't do much good if undefined behaviour is replaced by wrong behaviour. If a man's name won't fit in your string field, what are you going to do about it? Lots of possible answers, but just chopping it is unlikely to be acceptable - you get complaints about that sort of thing.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-09-02 10:42 +0100 |
| Message-ID | <87fupitz86.fsf@bsb.me.uk> |
| In reply to | #93090 |
will hunt <glovepm@gmail.com> writes: > should I use strncpy or snprintf, and why? ...(from the subject line) to copy a string safely and efficiently in C? I vote for neither. Several people have explained why strncpy is out -- never use it unless you know its dangerous peculiarities happen to be *exactly* what you need -- but snprintf, though safe, is rather complicated for the job and requires a relatively recent C library. One simple solution is to use strncat(dst, src, n). This concatenates two strings by adding at most n characters from src to those already present in dst. To use it for copying, dst must contain an empty string, and you need to remember that a terminating null byte is added in addition to the characters that get copied. This means you would write something like this char copy[STR_SIZE]; *copy = 0; strncat(copy, src, STR_SIZE - 1); -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2016-09-04 22:23 -0700 |
| Message-ID | <kfninuanclx.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #93100 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> will hunt <glovepm@gmail.com> writes:
>
>> should I use strncpy or snprintf, and why?
>
> ...(from the subject line) to copy a string safely and efficiently in C?
>
> I vote for neither. Several people have explained why strncpy is out --
> never use it unless you know its dangerous peculiarities happen to be
> *exactly* what you need -- but snprintf, though safe, is rather
> complicated for the job and requires a relatively recent C library.
>
> One simple solution is to use strncat(dst, src, n). This concatenates
> two strings by adding at most n characters from src to those already
> present in dst. To use it for copying, dst must contain an empty
> string, and you need to remember that a terminating null byte is added
> in addition to the characters that get copied. This means you would
> write something like this
>
> char copy[STR_SIZE];
> *copy = 0;
> strncat(copy, src, STR_SIZE - 1);
Or maybe this (with the same declaration of 'copy')
strncat( strcpy( copy, "" ), src, STR_SIZE-1 );
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-09-04 23:20 -0700 |
| Message-ID | <ln60qaamvx.fsf@kst-u.example.com> |
| In reply to | #93202 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
[...]
>> char copy[STR_SIZE];
>> *copy = 0;
>> strncat(copy, src, STR_SIZE - 1);
>
> Or maybe this (with the same declaration of 'copy')
>
> strncat( strcpy( copy, "" ), src, STR_SIZE-1 );
Interesting. It's easy to forget that strcpy() returns a result,
since that result is rarely useful and usually ignored.
(I'm resisting the temptation to repeat the warning that simple
truncation isn't always the correct response to an overflow.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | mark.bluemel@gmail.com |
|---|---|
| Date | 2016-09-05 01:03 -0700 |
| Message-ID | <5592dce1-cdc3-4eef-8d69-4d4d3f4556fb@googlegroups.com> |
| In reply to | #93204 |
On Monday, 5 September 2016 06:53:29 UTC+1, Keith Thompson wrote: > Tim Rentsch <txr@alumni.caltech.edu> writes: > > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > [...] > >> char copy[STR_SIZE]; > >> *copy = 0; > >> strncat(copy, src, STR_SIZE - 1); > > > > Or maybe this (with the same declaration of 'copy') > > > > strncat( strcpy( copy, "" ), src, STR_SIZE-1 ); > > Interesting. It's easy to forget that strcpy() returns a result, > since that result is rarely useful and usually ignored. > > (I'm resisting the temptation to repeat the warning that simple s/resisting/unsuccessfully resisting/ > truncation isn't always the correct response to an overflow.) FTFY
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-09-05 01:46 -0700 |
| Message-ID | <lnwpiq91js.fsf@kst-u.example.com> |
| In reply to | #93215 |
mark.bluemel@gmail.com writes:
> On Monday, 5 September 2016 06:53:29 UTC+1, Keith Thompson wrote:
[...]
>> (I'm resisting the temptation to repeat the warning that simple
> s/resisting/unsuccessfully resisting/
>> truncation isn't always the correct response to an overflow.)
>
> FTFY
Good point (but unsuccessful resistance is still resistance, futile
though it may be).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-09-05 10:30 +0100 |
| Message-ID | <87bn02zoau.fsf@bsb.me.uk> |
| In reply to | #93204 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > [...] >>> char copy[STR_SIZE]; >>> *copy = 0; >>> strncat(copy, src, STR_SIZE - 1); >> >> Or maybe this (with the same declaration of 'copy') >> >> strncat( strcpy( copy, "" ), src, STR_SIZE-1 ); > > Interesting. It's easy to forget that strcpy() returns a result, > since that result is rarely useful and usually ignored. For some reason, I find I use the return value of strcpy (and the others) quite often. Maybe too much LISP in my youth. But when I want an expression to do the job in question, I write (or, more accurately, have written in the past) strncat((*copy = 0, copy), src, STR_SIZE-1) so while I so use the value of strcpy, I've never thought to use it to write the null as Tim did. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2016-09-10 11:25 -0700 |
| Message-ID | <kfnwpijlihv.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #93219 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Keith Thompson <kst-u@mib.org> writes: > >> Tim Rentsch <txr@alumni.caltech.edu> writes: >>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> >> [...] >> >>>> char copy[STR_SIZE]; >>>> *copy = 0; >>>> strncat(copy, src, STR_SIZE - 1); >>> >>> Or maybe this (with the same declaration of 'copy') >>> >>> strncat( strcpy( copy, "" ), src, STR_SIZE-1 ); >> >> Interesting. It's easy to forget that strcpy() returns a result, >> since that result is rarely useful and usually ignored. > > For some reason, I find I use the return value of strcpy (and the > others) quite often. Maybe too much LISP in my youth. But when I want > an expression to do the job in question, I write (or, more accurately, > have written in the past) > > strncat((*copy = 0, copy), src, STR_SIZE-1) > > so while I so use the value of strcpy, I've never thought to use it to > write the null as Tim did. A different way of thinking of it is not writing a null but initializing 'copy' to an empty string, so the strncat() can then concatenate the 'src' string onto that empty string. That ideation may suggest using strcpy() more naturally. Personally I find this framing more attractive, because both operations are occurring at the same level of abstraction. (And I readily confess to using the '*copy = 0' method myself at times.)
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2016-09-11 06:23 -0700 |
| Message-ID | <kfnsht6lgee.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #93204 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > > [...] > >>> char copy[STR_SIZE]; >>> *copy = 0; >>> strncat(copy, src, STR_SIZE - 1); >> >> Or maybe this (with the same declaration of 'copy') >> >> strncat( strcpy( copy, "" ), src, STR_SIZE-1 ); > > Interesting. It's easy to forget that strcpy() returns a result, > since that result is rarely useful and usually ignored. I would say that slightly differently. The return value of strcpy() (and other str...() functions) is rarely used, because people forget that these functions return a result. In many (or most?) cases that happens because people are used to thinking imperatively more than functionally. These return values are actually useful noticeably more often than they are used.
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web