On 06/07/15 21:31, Rick C. Hodgin wrote:
> On Monday, July 6, 2015 at 3:54:20 PM UTC-4, Richard Bos wrote:
>> "Rick C. Hodgin" <
rick.c...@gmail.com> wrote:
>>
<snip>
>> >
>> > [...] So why isn't there a version like printf() which doesn't
>> > put a trailing NULL the way sprintf() does, but one that does so
>> > to a memory block?
>>
>> For the same reason that there isn't a version of fopen() which
>> automatically puts ".txt" at the end of all your filenames: it's going
>> to be of extremely limited use, so limited that it has no job in any
>> general library let alone the Standard one.
>
> I don't really see how it could be of limited use. The sprintf()
> function has exceeding utility. It is only in this one area where
> it forces a trailing NULL that it is an issue.
First, a terminology point. In C, "NULL" refers to a macro that expands
to an implementation-defined null pointer constant. The character that
terminates a string is known as a "null character".
Now, to the substance of your point. C supports two distinct kinds of
data (one of which is a subset of the other): completely arbitrary
(which we normally refer to as 'binary'), and text. The text format is
clearly intended to be human-readable, whereas binary is not quite so
friendly. Although there is no hard-and-fast rule about it, we generally
think of some functions as being suitable for manipulating text, and
others as suitable for manipulating binary data. For example, fopen(fn,
"r") is generally used when we expect the data file to contain
human-readable text, and fopen(fn, "rb") when we expect arbitrary data.
We use fgets, fprintf, and so on for reading and writing text, and
fread, fwrite for reading and writing binary data. We use mem* for
manipulating binary data, and str* for manipulating strings of
human-readable text. The whole idea of strings is all to do with
human-readable text. That doesn't mean we can't write programs that read
text files produced by another program and perform processing based on
that input, or that we can't write programs that produce text output
intended for input to another program. But, throughout, the assumption
is that *at some point* a human may have to read this stuff, so we keep
to printable, readable characters rather than arbitrary bit patterns.
The null character is an intrinsic part of the C string model.
When we start to confuse these two ideas, text and binary, we are likely
to run into problems - not necessarily insurmountable problems, but
problems nonetheless.
Formatted output is generally intended for human-readable text, and so
it makes sense to provide printf, fprintf, sprintf, and so on. These
functions work with strings because strings are how our programs
interact with humans. And, because they work with strings, they use null
characters to terminate those strings.
The mem* functions are generally used for manipulating binary data. To
provide a memprintf function would be to confuse the two models, to
little if any gain (as far as I can recall, you're the first person I've
encountered in comp.lang.c who has ever expressed a desire for a
memprintf function), and at the considerable cost of blurring the
distinction between binary data and text data.
In short, the game isn't worth the candle.
> And in googling
> today to try to find a solution, I was able to find where several
> people had asked the same question.
Were any of these people asking in comp.lang.c? I don't recall such a
thread, but then it's been quite a while since I read every single
article posted on comp.lang.c, so I may have missed it.
> I can just see wrapping all of the printf-related functions into
> a single function with a few flags, and one of them being "include
> a trailing null" and that being that. A tiny up-front wrapper
> that passes false in on memprintf() and true on sprintf(). Seems
> so simple that it would've been worth the tiny effort by the C
> devs back in the day.
Such a change would fill a much-needed gap.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within