How to specify field width with a variable? - c

I wanted to know if you can use a variable to specify field width, for example:
float g = 123.4567;
int x = 3;
int y = 4;
printf("%(%d).(%d)f", x,y,g);
I want my output to be: "123.4567", basically the same as
printf("%3.4f");
I don't think the compiler will read the current format, but maybe there is another way.

Is this question about C? I saw the q tag but I'm not sure, as you talk about compiler...
Anyway, in C it is done with *:
* The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
.* The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
printf ("Width trick: %*d \n", 5, 10);
Width trick: 10
http://www.cplusplus.com/reference/cstdio/printf/

Related

How to use format specifiers to set field width of a string?

printf("%5s\n", "#");
gives:
#
Is their a way to set field width of this string using an integer format specifier?
Something like this,
printf("%%ds\n", 5, "#");
From the printf manual
Instead of a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the field width is given in the next argument, or in the m-th argument, respectively, which must be of type int.
So in your example it would be:
printf("%*s\n", 5, "#");

What is the difference between %d and %*d in c language?

What is %*d ? I know that %d is used for integers, so I think %*d also must related to integer only? What is the purpose of it? What does it do?
int a=10,b=20;
printf("\n%d%d",a,b);
printf("\n%*d%*d",a,b);
Result is
10 20
1775 1775
The %*d in a printf allows you to use a variable to control the field width, along the lines of:
int wid = 4;
printf ("%*d\n", wid, 42);
which will give you:
..42
(with each of those . characters being a space). The * consumes one argument wid and the d consumes the 42.
The form you have, like:
printf ("%*d %*d\n", a, b);
is undefined behaviour as per the standard, since you should be providing four arguments after the format string, not two (and good compilers like gcc will tell you about this if you bump up the warning level). From C11 7.20.6 Formatted input/output functions:
If there are insufficient arguments for the format, the behavior is undefined.
It should be something like:
printf ("%*d %*d\n", 4, a, 4, b);
And the reason you're getting the weird output is due to that undefined behaviour. This excellent answer shows you the sort of things that can go wrong (and why) when you don't follow the rules, especially pertaining to this situation.
Now I wouldn't expect this to be a misalignment issue since you're using int for all data types but, as with all undefined behaviour, anything can happen.
When used with scanf() functions, it means that an integer is parsed, but the result is not stored anywhere.
When used with printf() functions, it means the width argument is specified by the next format argument.
The * is used as an indication that the width is passed as a parameter of printf
in "%*d", the first argument is defined as the total width of the output, the second argument is taken as normal integer.
for the below program
int x=6,p=10;
printf("%*d",x,p);
output: " 10"
the first argument ta passed for *, that defines the total width of the output... in this case, width is passed as 6. so the length of the entire output will be 5.
now to the number 10, two places are required (1 and 0, total 2). so remaining 5-2=3 empty string or '\0' or NULL character will be concatenated before the actual output

Does %*d mean one or more integer?

Does %*d mean one or more integer? in sprintf function
It is used to manipulate the minimum width of the numerical value printed, and it specifically means that the width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. In other words, if you wanted to use a width that was stored in a variable, you could do this:
int width = /* something */;
printf("%*d", width, value);
EDIT: Oops! Correct syntax for sprintf is:
sprintf(buffer, "%*d", width, value);
In the case of sprintf, it means you'll pass two integers, one specifies the field width, and the other the value you're going to convert.
IOW:
sprintf(buffer, "%5d", value);
is essentially the same as:
sprintf(buffer, "%*d", 5, value);
Much like when you're passing values as widths as literals in the format string, you can specify both a width and a precision if you want, something like this:
sprintf(buffer, "%*.*d", 5, 2, value);
It's also worth noting that with scanf and company, a "*" in the format string has a completely different meaning (to convert some input, but not assign the result to anything).
It is similar to %2d, which is "print a 2 length integer", except the length is specified as a parameter (not sure the order). Reference
The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
The * refers to a the width or spacing of the integer in this case. The * is a place holder that lets you specify the width as an argument preceding the argument to be formatted (the integer in this case)
printf("The integer will be printed 10 spaces to the right: %*d", 10, 50);

typecasting syntax not clear

I was reading a book and came across a program to read entries from a /proc file.
The program which they mentioned has following line
printf("%.*s", (int) n, line);
I am not clear with meaning of above line
what type of print if above "%.*s used instead of %s
The code can be read here
Abstract from here:
.* - The precision is not specified in
the format string, but as an
additional integer value argument
preceding the argument that has to be
formatted.
So this prints up to n characters from line string.
The cast expression (int) n converts the value of n to type int. This is because the formatting specifier requires a plain int, and I assume (since you didn't include it) the variable n has a different type.
Since a different type, like size_t might have another size, it would create problems with the argument passing to printf() if it wasn't explicitly converted to int.

What does the %*s format specifier mean?

In some code that I have to maintain, I have seen a format specifier %*s . Can anybody tell me what this is and why it is used?
An example of its usage is like:
fprintf(outFile, "\n%*s", indent, "");
It's used to specify, in a dynamic way, what the width of the field is:
The width is not specified in the format string, but as an additional
integer value argument preceding the
argument that has to be formatted.
so "indent" specifies how much space to allocate for the string that follows it in the parameter list.
So,
printf("%*s", 5, "");
is the same as
printf("%5s", "");
It's a nice way to put some spaces in your file, avoiding a loop.
Don't use "%*s" on a buffer which is not NULL terminated (packed) thinking that it will print only "length" field.
The format specifier %4s outputs a String in a field width of 4—that is, printf displays the value with at least 4 character positions.
If the value to be output is less than 4 character positions wide, the value is right justified in the field by default.
If the value is greater than 4 character positions wide, the field width expands to accommodate the appropriate number of characters.
To left justify the value, use a negative integer to specify the field width.
References: Java™ How To Program (Early Objects), Tenth Edition
When used in printf and fprintf:
printf("%*s", 4, myValue); is equivalent to printf("%4s", myValue);
It displays the variable with minimum width, rest right-justified spaces. To left-justify the value, use a negative integer.
When used in scanf and sscanf:
/* sscanf example */
#include <stdio.h>
int main ()
{
char sentence []="Rudolph is 12 years old";
char str [20];
int i;
sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d\n",str,i);
return 0;
}
Output:
Rudolph -> 12
It is used to ignore a string.
* Causes fprintf to pad the output until it is n characters wide, where n is an integer value stored in the a function argument just preceding that represented by the modified type.
printf("%*d", 5, 10) //will result in "10" being printed with a width of 5.
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
e.g: printf("%*s", 4, myValue); is equivelant to printf("%4s", myValue);.

Resources