Printing int values with a user determined padding? [duplicate] - c

This question already has answers here:
Set variable text column width in printf
(2 answers)
Closed 9 years ago.
I'm pretty sure there's no way to do this, but I was wondering, so here goes...
Say I get several int values from the user, and I know for a fact that the 1st
value is the largest.
Any way I can use the length of the first int value as the padding when printing
the rest of the numbers?
Browsing the forum I found that you can determine the length of an int (n) like
this:
l = (int) log10(n) + 1;
Using padding of 5 a print would look like:
printf("%5d", n);
So what I want to know is whether or not there's a way to use l instead of 5...
Thank you!

Do it like so:
int n = <some value>;
int i = (int) log10(n) + 1;
printf("%*d", i, n);
The * serves as a placeholder for the width being passed as an argument to printf().

You can use also snprintf() to get the number of characters printed for a value thus:
char buff[100];
int width = snprintf (buff, sizeof(buff), "%d", number1);
But, however you get the desired width, you can just use the * format modifier:
printf( "%*d %*d\n", width, number1, width, number2);
That modifier uses the next argument to specify a dynamic width rather than one fixed in the format string.

Related

printf statement modification in C [duplicate]

This question already has answers here:
Can we use only one variable for many format descriptors in printf in C
(3 answers)
Closed 1 year ago.
Lets take an example: (in C)
consider we have inputted a,b; (say a=1,b=2)
expected output:
1 + i2
1 - i2
1 X i2
so i do
printf("%d + i%d \n %d - i%d \n %d X i%d ",a,b,a,b,a,b);
Here Iam using a,b 3 times in printf statement ,the same variable is being defined 3 times
This is a small example so only 3 times we are using a,b but in big problems this thing might become a tedious job.
so is their a better way or alternative way to do this ?
You can split your printf function into few printfs , as it will reduce the work of matching the number of format specifiers and the variables.
By the way , I think you could use a loop structure to reduce that further.
Maybe use this: (the character array a contains +,- and X. The for loop is to display the characters contained in a)
#include<stdio.h>
int main(int argc, char *argv[]){
char a[]="+-X";
int n1=1;
int n2=2;
for(int i=0;i<3;i++){
printf("%d %c i%d\n",n1,a[i],n2);
}
}

print float up to four place on either side

I am newbie, I am trying to print an float value upto four place on either side. For example 11.3 will be 0011.3000. For this I am using following line:-
float t = 11.3;
printf("%4.4f", t);
But I am getting 11.3000. So, is it even possible what i am trying to do? If yes then how? Thanks
The type of f is incorrect in your code fragment, it should be float or double.
To produce leading zeroes, use the 0 printf modifier and specify the minimum width expected, 9 characters in your example (4 places before the . plus the . plus 4 more places after the .).
The format is therefore %09.4f.
Here is the code:
#include <stdio.h>
int main() {
double t = 11.3;
printf("%09.4f\n", t);
return 0;
}
Output:
0001.3000
Note however that if the number is negative, you will only get 3 places before the . and if the number is too large in absolute value (<= -999.99995 or >= 9999.99995), the output will have more than 9 characters. If you mean to have 4 places before the . for negative values too, you should use % 010.4f: the number will then be prefixed with a space if positive and a - if negative:
#include <stdio.h>
int main() {
double t = 11.3;
printf("%09.4f\n", t);
printf("% 010.4f\n", t);
printf("% 010.4f\n", -t);
return 0;
}
Output:
0011.3000
0011.3000
-0011.3000
float t = 11.3;
printf("%4.4f", t);
In your code above 4 before . means total number of characters to be printed.
and 4 after . mean number of characters after decimal.
Since you want xxxx.xxxx hence you should write it like:
printf("%9.4f", t);
The first part of the format spec is the width of the field you are printing in, not the number of digits before the decimal place. Your desired output has 9 characters in it, zero padded on the left, so do
float t = 11.3;
printf("%09.4f", t);
This might break down if for example the integer part of your number gets too big For a finer level of control, work with integers:
float t = 11.3;
int i, f;
i = (int)t;
f = (int)((t - i) * 10000 + 0.5);
printf("%04d.%04d", i, f);
All this assumes positive numbers. Neither example shown here will work properly with negatives.

snprintf + Pebble

I'm developing for Pebble and I'm off to a rough start.
I'm trying to populate a text_layer with 2 strings and 2 values, something like this:
WAIT AVG: 3 MAX: 5
Since malloc is not supported in Pebble SDK, I can't use sprintf, hence I'm stuck with snprintf. The following code only prints "4":
srand(time(NULL));
int average = (rand()%6)+1;
int maximum = average + 2;
static char *avgText="WAIT AVG: ";
static char *maxText="MAX: ";
snprintf(labelText,sizeof(avgText) + sizeof(average) + sizeof(maxText) + sizeof(maximum),"%s %d %s %d",avgText,average,maxText,maximum);
Any help would be greatly appreciated. I know that I can create 4 separate TextLayers but that's kind of a last resort for me.
You're just using snprintf wrong. ;-)
The second parameter (which you're trying to calculate, badly) is the length of the character array that you're printing into, not the number of characters you're trying to write.
Something like this should work:
char labelText[64]; // Is this big enough?
snprintf(labelText, 64,"%s %d %s %d",avgText,average,maxText,maximum);
sizeof(avgText) and sizeof(maxText) are sizes of pointers, not array sizes. See e.g. here. Change your code to
static char avgText[] = "WAIT AVG: ";
static char maxText[] = "MAX: ";
in order to make them arrays.
edit:
Further note, that sizeof(average) is the size in bytes average covers internally, not how many bytes a decimal representation would consume.
edit2:
As Roddy's answer says, it's wrong to calculate the size we want to have and pass that size to snprintf as an actual buffer size. We can, however, calculate the size we want to have provided there is a reasonable upper bound (e.g. with 32 bit int, 10 bytes (without 0-terminator) are always sufficient, but maybe you can give a lower upper bound in your use case):
char labelText [
sizeof avgText - 1 + 10 +
sizeof maxText - 1 + 10 + 3 + 1
];
/* sizeof avgText counts the 0-terminator, so does sizeof maxText, hence
the -1, two times 10 for the `int` (or any reasonable upper bound you have),
3 spaces and the 0-terminator. */
and you could even use sprintf. With snprintf, you can do:
snprintf(labelText, sizeof labelText,"%s %d %s %d", avgText, average, maxText, maximum);
HTH
read the man page of snprintf() properly. it says, the second argument size is used to refer to the number of bytes to be written.
sizeof (avgText) and sizeof(maxText)is not gonna work here. It refers to the size of the pointer, not the length of the array it holds. Maybe you want to use strlen() for the string length.
So this worked:
srand(time(NULL));
static char labelText[]="WAIT AVG: xxxxx MAX: xxxxxx";
int average = (rand()%6)+1;
int maximum = average + 2;
static char avgText[]="WAIT AVG: ";
static char maxText[]="MAX: ";
snprintf(labelText,sizeof(labelText),"%s %d %s %d",avgText,average,maxText,maximum);
text_layer_set_text(waitField,labelText);
thanks guys

How to get a blank output for an integer from printf [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
What value should be assigned to an integer in order to get a blank value displayed by printf in return when that integer is passed as an argument to it?
Although I assign a null value to the integer it prints 0
Can someone please suggest what can be done to achieve this?
Thank you
If you are instructing printf() to print an integer, there is no integer value that is represented by the empty string. There is no "null value" in the integer context, NULL in C is explicitly defined as being a zero value in pointer context. In integer context, 0 is simply a value. As for what should be done, use a conditional test to determine whether to call printf() or not, or use a conditional test to choose between using printf() to display an integer and using printf() (or another function) to display a string of spaces of some appropriate length.
'Blank values' are (empty) strings and no integer can result in a blank value.
There is no modifier for %d in printf to blank when zero; however, there are clearly times when you want to output blank for zeros in numerical output, specifically outputting a table of numbers where many are zero. If your set on using printf for this task then the following adjustment can be made to allow blanks when an int value is zero.
1 for (int i = 0; i < STOCKS; i++) {
2 char cur_str[4] = " ";
3
4 if (current_price[i]) sprintf(cur_str, "%+3d", current_price[i]);
5
6 printf(pcb[i+4], "%-15s%4d %4s %4d",
7 stocks[i], ph[year-1][i], cur_str, ph[year][i]);
8 }
Working backwards:
line 6-7 are the printf statement where the current price is to be displayed in the third column with the %4s option and corresponding cur_str argument
line 4 checks for a non-zero current price and uses sprintf to generate the right adjusted current price, when it is not zero, into cur_str
line 2 defaults cur_str to four spaces, the width of the column
Just convert the integer to a string and then strip the (leading) zero before giving it to printf:
v1=42
v2=0
printf '%2s %2s\n' "${v1#0}" "${v2#0}"
This prints 42 for v1 and two blanks for v2.
Works fine in the Bourne shell or Bash.
If there's a value you 100% absolutely know will never be used in that context, use that value as meaning "blank" and define (and use) a print_int_with_blank() function
#include <stdio.h>
#define IMPOSSIBLE_VALUE 42
int print_int_with_blank(char const *pre, int value, char const *post) {
int n = 0;
if (value != IMPOSSIBLE_VALUE) {
n = printf("%s%d%s", pre, value, post);
}
return n;
}
And you may use it like this
#include <stdio.h>
int main(void) {
int a[10];
for (int i = 0; i < 10; i++) {
a[i] = 7 * i;
}
print_int_with_blank("", a[0], "");
for (int i = 1; i < 10; i++) {
print_int_with_blank(", ", a[i], "");
}
puts("");
}
See demo at ideone

Pascal's Triangle returning nonsense values

This is a homework project I was assigned some time ago... I've been successful in getting this far on my own, and the only hiccup I have left is (I believe) an issue with data types and overflow.
I've tried changing over to unsigned and double, and the code complies and still accepts input in the terminal, but it seems to hang up after that... nothing is printed and it looks like it's caught in a loop.
Here is the code...
/* pascaltri.c
* A program that takes a single integer as input and returns the nth line of
* Pascal's Triangle. Uses factorial() function to help find items of
* individual entries on a given row.
*/
#include <stdio.h>
#include <stdlib.h>
long factorial(long i)
{
long fact = 1;
while(i > 1)
{
fact = fact * i;
i = i - 1;
}
return fact;
}
main(void)
{
long n;
long *nPtr;
nPtr = &n;
scanf(" %i", nPtr);
if (n >= 0)
{
long k;
long *kPtr;
kPtr = &k;
for(k = 0; k <= n; k++)
{
long ans;
long *ansPtr;
ansPtr = &ans;
ans = factorial(n) / (factorial(k) * factorial(n - k));
printf("\n %i", ans);
}
return 0;
}
return 0;
}
It's not perfect or pretty, but it works up to an input of 13 (that is, row 14) of the triangle. Beyond that I start getting gibberish and even negative values sprinkled throughout the returns... much larger values break the code and return nothing but an exit error message.
Any ideas on how I can correct this problem? I've been staring at the screen for much to long to really see anything myself. Also, it's not essential, but I would like to print my return values on one line, rather than having them separated by a newline character.
1 5 10 10 5 1
Would the easiest way be to load the values into an array as they are computed, and then print the array? Or is there a built-in way I can tell the print statement to occur on only one line?
You are suffering from integer overflow. You may need to find a different approach to the algorithm to avoid having to calculate the large numbers.
In answer to your other point about the newline, you are explicitly printing the newline with the \n in your print statement. Remove it, and you will get answers printed on one line. You probably want to inlucde a final printf("\n"); at the end so the whole line is terminated in a newline.
Some other observations:
You don't need the first return 0; - the control will drop out of
the bottom of the if block and on to the second (should be only)
return 0; and not cause any problems.
You're declaring kPtr but not using it anywhere
You don't need to declare a separate variable nPtr to pass to scanf; you can pass &n directly.
For the garbage, you are most likely running into an integer overflow, that is, your calculated values become too large for the long data type. You should correct it by calculating your factorial function without explicitely calculating n!.
Change scanf(" %i", nPtr); to
scanf(" %ld", nPtr);
and printf("\n %i", ans); to
printf("\n %ld", ans);
to get printout on one line, use:
printf(" %ld", ans);
If you are using gcc, turn on warnings, i.e. use -Wall.

Resources