Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

snprintf for fprintf

5 views
Skip to first unread message

Jonathan

unread,
Jun 10, 2008, 1:57:06 AM6/10/08
to
Hi,

Can you please tell me how can I printf 'n' characters of from a char*
to a file.

I notice there is a snprinf, but I don't see one corresponding to
fprintf?

I am thinking if i can do that without an extra memcpy.

Thank you for any help.
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Carl Barron

unread,
Jun 12, 2008, 8:23:30 PM6/12/08
to
In article <clcm-2008...@plethora.net>, Jonathan
<Jonathan...@gmail.com> wrote:

> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?
>
> I am thinking if i can do that without an extra memcpy.
>

if the string is at least n chars long see fwrite(), Otherwise
you need to write what you have and and fill to n chars.

Dag-Erling Smørgrav

unread,
Jun 12, 2008, 8:24:58 PM6/12/08
to
Jonathan <Jonathan...@gmail.com> writes:
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.

There are to ways to do this: use a field precision, or use fwrite().

#include <stdio.h>

int main(void)
{
FILE *f;
char *buf;
size_t len;

/* open f */
/* allocate and fill buf */

len = 10;
fprintf(f, "%.*s", (int)len, buf);
fwrite(buf, 1, len, f);

/* release buf */
/* close f */

return 0;
}

Note that if the number of characters you want to print is a constant,
you can use the following instead:

fprintf(f, "%.10s\n", buf);

There is an important difference between fprintf() with a field
precision and fwrite():

- fprintf() expects buf to be a string, and if that string is shorter
than the specified precision, fprintf() will stop at the end of the
string.

- fwrite() does not require buf to be a string, and will always write
the specified number of characters. If buf *is* a string, and it is
shorter than the specified length, fwrite() will write the string
followed by its terminating '\0' and garbage. Therefore, fwrite()
should only be used when you know in advance that the string is as
long as, or longer than the length you specify.

Example:

strcpy(buf, "superworldunknown");
strcpy(buf, "hello"); /* clobbers previous contents */
fprintf(f, "%.11s", buf);
fwrite(buf, 1, 11, f);

The fprintf() call will write "hello", while the fwrite() call will
write "hello\0world".

DES
--
Dag-Erling Smørgrav - d...@des.no

Friedrich Dominicus

unread,
Jun 12, 2008, 8:25:01 PM6/12/08
to
Jonathan <Jonathan...@gmail.com> writes:

> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?
>
> I am thinking if i can do that without an extra memcpy.

fprintf(out, "%.10s", "what I like to print");

Regards
Friedrich

--
Please remove just-for-news- to reply via e-mail.

Iman S. H. Suyoto

unread,
Jun 12, 2008, 8:25:05 PM6/12/08
to
Jonathan wrote:
> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?

How about:

char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n = 5;

.
.
.

if (fprintf(fp, "%.*s", n, s) != n) {
fprintf(stderr, "Error...\n");
.
.
.
}

If the first fprintf() invocation is successful, only "ABCDE" is written.

Kevin Ashley

unread,
Jun 12, 2008, 8:25:09 PM6/12/08
to
Jonathan wrote:
> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?
>
> I am thinking if i can do that without an extra memcpy.
>

Look closer at the documentation for fprintf and its friends.
Look in particular at the meaning of the 'precision' and
'width' modifiers when using %s to print a string. You
should then find what you seek.

Thomas Richter

unread,
Jun 12, 2008, 8:30:43 PM6/12/08
to
Jonathan schrieb:

> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?

Not required if all you want to print is a string.

fprintf(file,"%0.*s",n,string);

So long,
Thomas

Minimiscience

unread,
Jun 12, 2008, 8:32:06 PM6/12/08
to
On 10 Jun 2008, 05:57:06 UTC, Jonathan declared to all in comp.lang.c.moderated:

> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.

Allocate a character array n+1 bytes long, use snprintf() to write the n bytes
you want to print to that, and then use fputs() or fprintf("%s", str) to print
the string.

> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?

There isn't one. snprintf() exists so that you don't have to worry about
buffer overflow when writing to a string. Since the possibility of writing too
many characters to a file is beyond the scope of standard C, and as the
workaround is so simple, there wasn't much reason to add it to the language.

--
I'm not random --- I'm just rand().

Barry Schwarz

unread,
Jun 12, 2008, 8:32:09 PM6/12/08
to
On Tue, 10 Jun 2008 00:57:06 -0500 (CDT), Jonathan
<Jonathan...@gmail.com> wrote:

>Hi,
>
>Can you please tell me how can I printf 'n' characters of from a char*
>to a file.
>
>I notice there is a snprinf, but I don't see one corresponding to
>fprintf?
>
>I am thinking if i can do that without an extra memcpy.
>
>Thank you for any help.

Look up the modifiers to the %s format specification in you reference.


Remove del for email

Prashu

unread,
Jun 12, 2008, 8:32:11 PM6/12/08
to
I think u can use the fwrite() for this purpose to write only first n
characters..

as its syntax is
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE *
stream );

ex:
fwrite (buffer , 1 , sizeof(buffer) , pFile );

instead of sizeof(buffer) .. u can use how many characters u want to
write....

azha...@gmail.com

unread,
Jun 12, 2008, 8:33:02 PM6/12/08
to
On Jun 10, 10:57 am, Jonathan <Jonathan.Cran...@gmail.com> wrote:
> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?
>
> I am thinking if i can do that without an extra memcpy.
>
> Thank you for any help.
> --
> comp.lang.c.moderated - moderation address: c...@plethora.net -- you must

> have an appropriate newsgroups line in your header for your mail to be seen,
> or the newsgroup name in square brackets in the subject line. Sorry.

use this
fprintf(fp,"%.*s",n,str);

Dag-Erling Smørgrav

unread,
Jun 14, 2008, 4:01:44 AM6/14/08
to
Minimiscience <minimiscie...@gmail.com> writes:

> Jonathan <Jonathan...@gmail.com> writes:
> > Can you please tell me how can I printf 'n' characters of from a char*
> > to a file.
> Allocate a character array n+1 bytes long, use snprintf() to write the n bytes
> you want to print to that, and then use fputs() or fprintf("%s", str) to print
> the string.

That works, but it's hardly the best (or simplest) solution, and it's
specifically not what the OP asked about.

> > I notice there is a snprinf, but I don't see one corresponding to
> > fprintf?
> There isn't one. snprintf() exists so that you don't have to worry about
> buffer overflow when writing to a string. Since the possibility of writing too
> many characters to a file is beyond the scope of standard C, and as the
> workaround is so simple, there wasn't much reason to add it to the language.

That is wrong in so many ways I don't even know where to begin... You
need to read a) your compiler's documentation for printf() and fwrite(),
b) other people's answers to Jonathan, and c) the relevant parts of the
C standard.

DES
--
Dag-Erling Smørgrav - d...@des.no

Nick Landsberg

unread,
Jun 18, 2008, 9:45:27 AM6/18/08
to
Jonathan wrote:
> Hi,
>
> Can you please tell me how can I printf 'n' characters of from a char*
> to a file.
>
> I notice there is a snprinf, but I don't see one corresponding to
> fprintf?
>
> I am thinking if i can do that without an extra memcpy.
>
> Thank you for any help.

There have been several convoluted solutions presented.
The simplest is in the man page for the printf
family of functions.

s The char * argument is expected to be a pointer to an array of
character type (pointer to a string). Characters from the
array
are written up to (but not including) a terminating NUL
charac-
ter; if a precision is specified, no more than the number
speci-
fied are written. If a precision is given, no null character
need be present; if the precision is not specified, or is
greater
than the size of the array, the array must contain a
terminating
NUL character.

There is also a paragraph or two describing how to specify
precision earlier in that page. If I recall correctly
the format "%12.12s" will ouput exactly 12 characters
padded with blanks if the original is less than 12
characters.


--
"It is impossible to make anything foolproof
because fools are so ingenious"
- A. Bloch

Keith Thompson

unread,
Jun 28, 2008, 8:03:59 PM6/28/08
to
Nick Landsberg <SPAMhuk...@SPAMworldnetTRAP.att.net> writes:
[...]

> There have been several convoluted solutions presented.
> The simplest is in the man page for the printf
> family of functions.
>
> s The char * argument is expected to be a pointer to
> an array of character type (pointer to a string).
> Characters from the array are written up to (but not
> including) a terminating NUL character; if a precision is
> specified, no more than the number specified are written.

> If a precision is given, no null character need be present;
> if the precision is not specified, or is greater than the
> size of the array, the array must contain a terminating
> NUL character.
[...]

Note that this wording is not quite correct. The char* argument is
expected to be a pointer to *the first element of* an array of
character type, not a pointer to the array itself.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Andrei Voropaev

unread,
Jul 4, 2008, 2:46:52 AM7/4/08
to
On 2008-06-29, Keith Thompson <ks...@mib.org> wrote:
> Nick Landsberg <SPAMhuk...@SPAMworldnetTRAP.att.net> writes:
[...]
>> s The char * argument is expected to be a pointer to
>> an array of character type (pointer to a string).
[...]
> Note that this wording is not quite correct. The char* argument is
> expected to be a pointer to *the first element of* an array of
> character type, not a pointer to the array itself.

Sorry to bother, but can you clarify what is the difference? AFAIK every
"pointer to array" in C is pointer to the "first element" of the
array. So, why would one need to replace more understandable thing with
less understandable while both mean the same?

--
Minds, like parachutes, function best when open

Keith Thompson

unread,
Jul 8, 2008, 3:29:32 PM7/8/08
to
Andrei Voropaev <avo...@mail.ru> writes:
> On 2008-06-29, Keith Thompson <ks...@mib.org> wrote:
>> Nick Landsberg <SPAMhuk...@SPAMworldnetTRAP.att.net> writes:
> [...]
>>> s The char * argument is expected to be a pointer to
>>> an array of character type (pointer to a string).
> [...]
>> Note that this wording is not quite correct. The char* argument is
>> expected to be a pointer to *the first element of* an array of
>> character type, not a pointer to the array itself.
>
> Sorry to bother, but can you clarify what is the difference? AFAIK every
> "pointer to array" in C is pointer to the "first element" of the
> array. So, why would one need to replace more understandable thing with
> less understandable while both mean the same?

Because they don't mean the same thing. They're of different types.

Here's a concrete example:

char s[6] = "hello";
char *p1 = &s[0]; /* p1 is a pointer to char */
char (*p2)[6] = &s; /* p2 is a pointer to array of char */

p1 and p2 point to the same location in memory, but they don't point
to the same object; one points to a single byte, the other points to a
6-byte object.

For any two distinct types foo and bar, the types pointer-to-foo and
pointer-to-bar are distinct types. This is equally true even if foo
happens to be an array of bar, or vice versa.

See also sections 4 and 6 of the comp.lang.c FAQ,
<http://www.c-faq.com>.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Jasen Betts

unread,
Jul 10, 2008, 2:02:38 PM7/10/08
to
On 2008-07-04, Andrei Voropaev <avo...@mail.ru> wrote:
> On 2008-06-29, Keith Thompson <ks...@mib.org> wrote:
>> Nick Landsberg <SPAMhuk...@SPAMworldnetTRAP.att.net> writes:
> [...]
>>> s The char * argument is expected to be a pointer to
>>> an array of character type (pointer to a string).
> [...]
>> Note that this wording is not quite correct. The char* argument is
>> expected to be a pointer to *the first element of* an array of
>> character type, not a pointer to the array itself.
>
> Sorry to bother, but can you clarify what is the difference? AFAIK every
> "pointer to array" in C is pointer to the "first element" of the
> array. So, why would one need to replace more understandable thing with
> less understandable while both mean the same?

The array has size n (depending on how big it is)
the first element (being a char) has size 1

#include <stdio.h>
int main(void)
{
char a[2][4]={"foo","bar"};

char *c=a[0]; // pointer to a char
char (*p)[4]=a; // pointer to an array of 4 chars

printf("c=%s\n",c); // here ther appear the same
printf("p=%s\n",p);
printf("c+1=%s\n",c+1); // here the difference is exposed.
printf("p+1=%s\n",p+1);

return 0;
};

Bye.
Jasen

Keith Thompson

unread,
Jul 12, 2008, 7:10:21 PM7/12/08
to

(You don't want the extra semicolon at the end of the definition of
main().)

Note that the %s format expects an argument of type char*. You should
cast the arguments to the expected type:

Or you could use "%p" to show the values of the pointers (with a cast
to void*), or print sizeof *c and sizeof *p.

Here's a version of your program showing all three techniques:

#include <stdio.h>
int main(void)
{
char a[2][4] = {"foo", "bar"};

char *c = a[0]; /* pointer to a char */
char (*p)[4] = a; /* pointer to an array of 4 chars */

printf("c = \"%s\"\n", (char*)c); /* here they appear the same */
printf("p = \"%s\"\n", (char*)p);
printf("c+1 = \"%s\"\n", (char*)(c+1));
/* here the difference is exposed. */
printf("p+1 = \"%s\"\n", (char*)(p+1));

printf("c = %p\n", (void*)c); /* here they appear the same */
printf("p = %p\n", (void*)p);
printf("c+1 = %p\n", (void*)(c+1));
/* here the difference is exposed. */
printf("p+1 = %p\n", (void*)(p+1));

printf("sizeof *c = %lu\n", (unsigned long)sizeof *c);
printf("sizeof *p = %lu\n", (unsigned long)sizeof *p);

return 0;
}

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

0 new messages