I thought it would print:
h
he
hel
hell
hello
but I got:
hello
hello
hello
hello
hello
Does the asterisk not work with the s descriptor? Or, am I using it wrong.
Is there another way to do this (except fwrite)?
--
Kevin Buchs 3500 Zycad Dr. Oakdale, MN 55109 (612)779-5548
Zycad Corp. {rutgers,ihnp4,amdahl,umn-cs}!meccts!nis!zycad!kjb
I think the reason is that the i would specify the minimum field
width, and in this case, the field would always be larger than that.
Running this will show you what is really going on here.
main() {
static char a[2] = "h";
int i;
for(i=0;i<6;i++)
printf("foo%*s string\n",i,a);
}
it looks like ->
fooh string
fooh string
foo h string
foo h string
foo h string
foo h string
So, in answer to your question: no, * sets a min. width not the actual
width. Perhaps you should look at the BSD routines which deal with
strings which are not null terminated i.e. you could copy the string
segement into one which is null terminated and then print that, but
it isn't really clear to me whether printing the pieces is important
to you.
William L. Moran Jr.
moran@{yale.arpa, cs.yale.edu, yalecs.bitnet} ...{ihnp4!hsi,decvax}!yale!moran
Gonna get my PhD...I'm a teenage lobotomy!
- The Ramones
The format "%8s" prints a string in a min field width of 8 characters.
The format "%.8s" trucactes a string to a max field width of 8.
I just tried it, and the same applies to a variable specified field:
try:
char *a = "hello"; int i;
for (i=0; i<6; i++) printf("%.*s\n", i, a);
which prints what you were expecting.
Neil/.
* here is the minimum field length , use .* for the precision. See
K&R pg 146-147. For your example you need:
for (i=0; i<6; i++) printf("%.*s\n", i, a);
Larry Cipriani AT&T Network Systems at
cbosgd!osu-cis!tut!lvc Ohio State University
printf("%.*s", i, string);
In a declaration of the form %10.5s, the 10 is the minimum width that the
string will take, being padded if necessary. The 5 is the maximum number
of characters from the string that will be printed.
Peter Moore
The number following the % is a width specifier, which in the case of a string >
is the minimum width to use. To specify the precision, the number should
follow the %, an optional width field, and a period. The following code
will produce the desired output:
char *cp; int i;
cp = "hello";
for (i=1;i<6;++i)
printf("%.*s\n",i+1,cp);
Eric Fauman - University of California - San Francisco
for (i=0; i<6; i++) printf("%*.s\n", i, a);
When printing a string (or anything else), the number immediately
after the % means the "field width" and represents the MINIMUM
amount of space the field should occupy in the output.
The number after the . means different things for different format
types; for strings it represents the MAXIMUM number of characters
transferred to the output.
> I want to print out a string whose length I will not know ahead, and which
> is not null terminated.
> [I tried] ... printf("%*s\n", i, a);
Most people pointed out that he meant "%.*s". However, according to the
ANSI Draft Standard, that usage is NOT portable. The reason is that the
Draft requires that the argument a "shall be a pointer to a string".
And a string is defined as "an array of characters *terminated by a null
character*" [my emphasis].
This means that an implementation may, on encountering the above, cheerfully
go on reading characters past the end of a until it runs off the end of
memory (or the segment of memory) and aborts... no matter what the value
of i is.
Fully portable ways to do this would be:
[1] { int j; for (j = 0; j < i; ++j) putchar (a[j]); }
putchar ('\n');
[2] { char *tmp = malloc (j+1); if (!tmp) abort();
strncpy (tmp, a, j); tmp[j] = 0;
printf ("%s\n", tmp); free (tmp); }
If you know a maximum size for a, you can avoid the malloc().
If a is known not to be const, there is also:
[3] if (j) { char last = a[j-1]; a[j-1] = '\0';
printf ("%s%c", a, last); a[j-1] = last; }
putchar ('\n');
It seems to me that both [1] and [2] are likely to be significantly slower
than the "%.*s" method, which I expect will work on most or all existing
implementations; and [3] is ugly and not always usable. I can't think
of another reasonable approach, anyway. (You can't use fwrite(), for
instance, because the Draft allows an implementation to distinguish text
streams from binary streams.)
Doug Gwyn pointed out the "string" requirement to me when I asked him by
email about the acceptability of printf ("%.1s", &char_variable) to print
a char unless it was a null. I agreed that this was a minor convenience
at best. But thinking about the above example, and what you'd have to do,
does make me wonder whether the Committee really considered this point
before deciding to restrict all forms of %s to "strings". They might have
decided that C was so strongly oriented to null-terminated strings that
anyone who wants to use data structures like a is doing so at their own
risk; or it might just have slipped by. You there, Doug?
Mark Brader, SoftQuad Inc., Toronto "Suspicion breeds confidence."
utzoo!sq!msb, m...@sq.com -- BRAZIL
Hi. I think the idea was that X3J11 wanted to allow the implementation
to be able to snarf up the argument with strcpy() etc. and this required
insisting that it be a properly-formed string. However, I might misremember.
> I think the idea was that X3J11 wanted to allow the implementation
> to be able to snarf up the argument with strcpy() etc.
I hope that's not all it was. "etc." says it. Use strncpy()!
There might also be case for removing the restriction on the grounds
of conformance with existing practice, depending on the behavior of
the widely used implementations. I'm sure I'm not the only one who's
assumed in good faith that the null was not needed.
I realize it's quite late, but the more I think about it the more I
think that the restriction is unreasonable and should be lifted.
What chance?
Mark Brader "The last 10% of the performance sought contributes
Toronto one-third of the cost and two-thirds of the problems."
utzoo!sq!msb, m...@sq.com -- Norm Augustine
Presumably if you get your comments into X3 or Tom Plum this week,
flagged as an "unsatisfactory response" received on one of your
formal review comments, X3J11 will be obliged to consider them at
the meeting next week. The plan is for this to be the last meeting
at which substantive changes to the draft proposed ANS will be made,
but nobody knows whether things will happen that way. So long as
we keep making changes, publication of the C standard keeps getting
delayed. A lot of people really want to get the standard out soon.