Ah, the sign of an interlocutor confident in his argument.
A string literal "IS" an intentional format string, no?
Only if the writer intended it to be one. That's what "intentional"
means.
Your assertion implied that a format string must contain a
conversion specifier.
It did no such thing. You inferred it, incorrectly.
But you most definately implied that it wasn't.
Wrong, but thanks for playing.
Sure they are, you just lack imagination.
Clearly they aren't, since you haven't compelled any agreement.
Let's check the score: so far you fail to understand the concept of
intent; the difference between implication and inference; and what
constitutes a compelling argument. You are pretty handy with the
brusque dismissal, though. Pity that doesn't constitute an argument.
Hmm... I'd wager the opposite is true.
The opposite of what? If you don't know the length of the source,
you *don't* have a potential buffer overrun? You'd lose that wager.
More-often what
matters is 'sizeof' destination.
Both matter, every time, as is obvious to anyone with any
comprehension of the language.
Consider this, regardless of source length,
with sprintf() I can do something along the lines of:
sprintf(buf, "%.*s", sizeof buf -1, src);
And you can do the equivalent with strncat (and it works in precisely
the same cases, ie when "buf" refers to an array type and not a
pointer type). And strncat has the following advantages:
- It's not variadic, so it's type-safe.
- It doesn't have to parse a format string, so it's almost certainly
more efficient.
- It doesn't require an extraneous string literal.
- It requires one fewer parameter, which is more efficient on some
implementations.
Also, your sprintf call, as written, is incorrect and I believe
invokes UB. The result of the sizeof operator has type size_t, so
"sizeof buf -1" has type size_t; when an asterisk is used as a field
width or precision specifier, it requires an argument of type int.
So we can add another:
- For some reason, many programmers seem to have difficulty using
sprintf correctly.
That's why sprintf is the wrong solution.
How does strcpy() save you even if the length of src is known?
I never said that it was. (And no, I did not imply it, either.)
I said that sprintf was the wrong solution, not that strcpy was
the right one.
Not necessarily. How did you determine the length of the source?
I think that ought to be left as an exercise for the reader. Here's
a hint: 7.21.6.3.
Trivial example (since you've never seen one) requirements:
Read lines from stdin until they are exausted.
Although line lengths vary, the maximum length of 1 line is
guaranteed not to exceed 255 bytes (including newline).
Each line (whose actual length must also be determined) needs
to be duplicated prior to calling functions to massage the data.
This one isn't compelling, either.
char buf[2][256];
while(fgets(buf[0], sizeof buf[0], stdin) != NULL) {
int len = sprintf(buf[1], "%s", buf[0]);
...
}
OK, so now you can see an example.
Try reading for comprehension. What I hadn't seen an example of
is a case "where using sprintf just to copy a string is justified".
You haven't justified it.
There is no potential for buffer overrun, agreed?
Why would there be?
One call to sprintf() copies the string and determines it's length.
(That's "its". No apostrophe in the possessive pronoun.)
So what? On what grounds do you claim this is superior to
determining the string's length and copying it with separate calls to
strlen and strcpy (or strlen and memcpy, or any other variation)?
Maybe I'm just naive and using the wrong solution, but if so, how
would you recommend I turn this garbage into a well-written program?
The obviously superior solution is strlen and strcpy. Still O(N),
without the overhead of sprintf, or the other problems listed above.
Uses the obvious approach, improving code clarity.
Very well. Show some data demonstrating that in a sizable minority
of cases, C programs do not need to know the length of the source
when copying strings.
Yes.
--
Michael Wojcik (e-mail address removed)
Painful lark, labouring to rise!
The solemn mallet says:
In the grave's slot
he lies. We rot. -- Basil Bunting