Trailing Zeros in printf/sprintf - c

I would like to make the output of a number to always have 6 digits
e.g.:
if number is 1 the output should be 100000
if number is 23 the output should be 230000
if number is 236 the output should be 236000
How can I do this with printf/sprintf?

printf and its variants can pad zeroes to the left, not to the right. sprintf the number, then add the necessary zeros yourself, or make sure the number is 6 digits long:
while(num < 100000)
num *= 10;
(This code assumes the number isn't negative, or you're going to get in trouble)

printf will return the number of character printed out. This you can print out the remaining zeros:
int num = 3; // init
int len = printf("%d", num);
for (int i = 0; i < 6-len; ++i)
printf("0");
You should add some error checks (for example, if len is larger than 6).
With sprintf, you can use memset on the remaining buffer, which will be easier.

You can't do it directly with printf (at least in a standard-conforming way), you need to alter your numbers beforehand.

Use the return value of printf (as in the first line of the for loop below)
#include <stdio.h>
int main(void) {
int number, width = 6;
for (number = 1; number < 9999999; number *= 7) {
int digits = printf("%d", number);
if (digits < width) printf("%0*d", width-digits, 0);
puts("");
}
return 0;
}
See code running at http://ideone.com/TolIv

As Luchian said, this behavior is unsupported in printf, unlike the much more common reverse (left) padding.
You could, however, easily enough generate the requested result with something like this:
char *number_to_six_digit_string(char *resulting_array, int number)
{
int current_length = sprintf(resulting_array, "%d", number);
while (6 > current_length) {
resulting_array[current_length++] = '0';
}
resulting_array[current_length] = '\0';
return resulting_array;
}
and then you could print the result:
char my_number[7];
printf("my number is %s, other stuff\n", number_to_six_digit_string(my_number, 13));

Related

String not showing up in console for C

I'm trying to convert a number in to a binary string:
void num_to_binary(const int num, char *binary) {
int number = num;
for(int i = 0; number > 0; i++){
binary[i] = number % 2;
number = number/ 2;
}
int length = strlen(binary);
binary[length] = '\0';
printf("%s", binary);
}
While I'm sure that the binary string contains what I want (I tested the code by using
printf("printed %d end",binary[i]); in the for loop), I was unable to print it out by writing the code printf("%s", binary);
Any suggestions would be much appreciated! Thank you.
you have to do binary[i] = !!(number % 2) + '0';, otherwise strlen() will find the null character (value zero) somewhere it shouldn't, it is probably the first character in your case. See the code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void num_to_binary(const int num, char *binary) {
int number = num;
for(int i = 0; number > 0; i++){
binary[i] = !!(number % 2) + '0';
number = number/ 2;
}
int length = strlen(binary);
binary[length] = '\0';
printf("%s", binary);
}
int main(void)
{
char buffer[100];
num_to_binary(25, buffer);
return 0;
}
The issue is that you're setting the values of a character string to either 1 or 0. When that string gets printed, those numbers are interpreted by the ASCII table. Both 1 and 0 represent unprintable characters. In fact, 0 is called a "null terminator" which will cause C to stop printing when it sees that value.
Instead, you want the ASCII representations of "1" and "0", which are 31 and 30, respectively. So, you could replace that line with
binary[i] = 30 + number % 2;
EDIT:
It should be 30 + !!(number % 2). That will take care of the situation when number is negative.
binary[i] = number % 2; in this line, you're just storing a integer value to a string. And every time the value is either 0 or 1. So, printf("%s", binary); shows the charactera corresponding to ASCII 0 or 1.
The ASCII value for character '0' is 48 and '1' is 49. You have two ways:
binary[i] = number % 2 + 48; or,
binary[i] = number % 2 + '0';

C random integer generator question (A book on C 4th Edition)

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n;
printf("\n%s\n%s",
"Some randomly distributed integers will be printed.",
"How many do yo want to see? ";
scanf("%d", &n);
for (i = 0; i < n; ++i) {
if (i % 10 == 0)
putchar('\n');
printf("%7d", rand());
}
printf("\n\n");
return 0;
}
this is the code from the textbook "A book on C".
when you type 23 when prompted it is supposed to generate 23 random numbers in 3 rows, 8 columns (3*8-1).
i learned that printf("%7d", rand())is supposed to return a value printed in a format of a decimal integer and the width of the field where the integer gets printed is 7.
however, I am getting random numbers that are in a width of more than 7 and it doesn't look neat at all. (no columns nor rows, just a huge chunk of consecutive numbers like 1235289043528935294835698246182965982)
I thought it has something to do with the expression printf("%7d", rand()) function and the way how it is supposed to return values.
I'm starting to think that the textbook is wrong.
Your numbers are bigger than 7 digits. You can try:
A) Changing the width field higher:
printf("%14d", rand() );
or
B) Making the generated numbers smaller than 7 digits:
printf("%7d", rand() % 1000 );
More information on format specifiers can be found here
Hope that helps!
You are not printing any whitespace. Try inserting some:
printf("%7d\t", rand());
In addition to the comment above, if I understand correctly you want all 8 numbers then the line should be changed to be: if (i % 8 == 0);
Rather than guess the maximum width of a rand() number, calculate the width of maximum random number: RAND_MAX.
snprintf(NULL, 0, ... prints the number of characters that would have been written had the buffer been sufficiently large, not counting the terminating null character.
int width = snprintf(NULL, 0, "%d", RAND_MAX);
Later when printing, use the width.
printf(" %*d", width, rand());
as in
#define COLUMN_N 8
for (i = 0; i < n; ++i) {
printf(" %*d", width, rand());
if (i % COLUMN_N == COLUMN_N - 1 || i + 1 == n) {
putchar('\n');
}
}

Why is the last element not appending to my array of digits?

Hi I am new to "C" I have a question on some output I got.
The number we are working with as data is: [4003600000000014].
I have every element appended to this array except for one I am not sure how to get the last number to print.
I am curious about the number 6422180 I am not sure what it is can someone explain.
// This is an example of Luhn's algorithm.
#include <stdio.h>
#include <ctype.h>
#define MAX_CRED_LEN 16
// Function prototypes.
void payment_method();
int main(void)
{
payment_method();
return 0;
}
long long int get_credit_card_num()
/*
Gets the users credit card number.
*/
{
long long int d;
do
{
printf("\nPlease enter in your credit card number: ");
if (scanf("%lld", &d) == 1)
{
printf("\nYour credit card number: (%lld)\n%s", d,
"------------------------\n\n");
continue;
}
else
{
printf("\n\tINVALID INPUT CHARACTER ENTERED PLEASE TRY AGAIN!\n%s",
"\t*************************************************");
fflush(stdin); // Clear input buffer of any characters!
get_credit_card_num(); // Start the function again to prompt user.
}
} while (d < 0);
return d;
}
int num_of_ccdigits()
/*
Counts the amount of digits the user entered. Then compares the number of
digits to a specific length offered by cardholders they are 13, 15, and 16
digits long.
*/
{
long long int cc_num = get_credit_card_num();
int digits = 0, arr[MAX_CRED_LEN];
// Count how many digits the user entered then compare the length.
while (cc_num != 0)
{
cc_num /= 10;
arr[digits] = cc_num % 10;
digits++;
}
// Display the number of digits that the user entered.
printf("\nNumber of digits: [%i]", digits);
int a = 0, i;
for (i = 0; i < digits; i++)
{
printf("\n[%d]:\tYOUR DIGIT ARRAY: %i", a, arr[i - 1]);
++a;
}
printf("\n\nARRAY WITHOUT LINE BREAKS: %i", arr);
// Check to see if this is a valid credit card number or a supported one.
if ((digits != 13) && (digits != 15) && (digits != 16))
{
printf("\n\tMUST BE AT LEAST 13, 15, AS HIGH AS 16 DIGITS.\n%s",
"\t**********************************************\n");
// if no 13, 15, or 16 digits long restart loop.
num_of_ccdigits();
}
return digits; // return the amount of digits in the credit card number.
}
void payment_method()
{
int num_of_digits = num_of_ccdigits();
}
I see a few issues here. For your first question, the code is indexing out of bounds of arr, causing undefined behavior:
for (i = 0; i < digits; i++)
{
printf("\n[%d]:\tYOUR DIGIT ARRAY: %i", a, arr[i - 1]);
++a;
}
On the first iteration, i = 0 and we proceed to index into arr[0 - 1] or arr[-1]. Whoops. This might produce a garbage value or cause a crash (or anything else).
By the way, a is redundant here--just use i to get the index (having to resort to a to get the index smells like something is off). The arr[i - 1] trick might have been done to compensate for another bug:
while (cc_num != 0)
{
cc_num /= 10;
arr[digits] = cc_num % 10;
digits++;
}
The problem here is that cc_num /= 10; says "move on to the next digit". But this skips the first digit completely. This should be:
while (cc_num != 0)
{
arr[digits] = cc_num % 10;
digits++;
cc_num /= 10;
}
Another problem which can be identified by turning on warnings is
ARRAY WITHOUT LINE BREAKS: -1747166688
Here, the compiler tells us the problem:
$ clang-7 -o main main.c
main.c:67:49: warning: format specifies type 'int' but the
argument has type 'int *' [-Wformat]
printf("\n\nARRAY WITHOUT LINE BREAKS: %i", arr);
~~ ^~~
1 warning generated.
To dump the array's values, use a loop and print each element individually.
Other remarks:
Invalid user entries cause an infinite loop.
Good job breaking things into functions, but try to avoid side effects in functions, especially printing. For example num_of_ccdigits does quite a lot more than simply getting the number of credit card digits. It also does validation and I/O. If you remove the print statements and make it responsible for purely counting the digits in a number, you can rename it count_digits(long long int num) and make it reusable on any long long int. Then, handle printing and validation elsewhere, say, print_digits(long long int num) and validate_cc_digit_length(long long int num). Check out single responsibility principle.
I'm a bit confused by the purpose of the function
void payment_method()
{
int num_of_digits = num_of_ccdigits();
}
Function names are typically actions, describing what the function does, rather than nouns, which are typically variables. Consider something like get_payment_method().
Also, since num_of_ccdigits calls itself recursively on bad data, it can potentially cause the stack to overflow. Using a while loop is a better way to handle bad input that can go on unbounded.
For initialization like:
int digits = 0, arr[MAX_CRED_LEN];
prefer:
int digits = 0;
int arr[MAX_CRED_LEN];
which is easier to read.

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

Converting int to char

Task is to get int using scanf("%d") then print it again using printf("%с") without standard functions like atoi , itoa .As i understood i need to divide all numbers then add \0 char and print it, however how can i divide it. I thought about loop for dividing number%10 + /0 and number/10 to decrease number for 1 character .
Therefore code should look smoothing like this
#include <conio.h>
#include <stdio.h>
main(void)
{
int number,reserve ;
char Array[50];
scanf_s("%d",&number);
if (number > 0 || number == 0)
{
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
else
{
number *= -1;
printf("-");
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
_getch();
return 0;
}
As well there can be negative number so i need some if statement to check if it is negative and in case it is loop should avoid it it so we won't get smthing like -%10
So i don't know if loop is correct (hope someone will fix it and explain me how it is supposed to be). Waiting for your advices.
One side effect of the line
number = number % 10;
is that you lose the original value of number. So when you go to do
number = number/10;
it would always get the value zero. To fix this, store the original value somewhere else, or use another variable to do your character conversion (modulo 10, then plus \0).
Also, your loop needs to be re-examined. This process of modulo, add \0, divide, repeat, should stop when the result of the division is zero (i.e. there are no more digits to print). Another thing to think about is: in what order are these digits being printed?
I'll leave it to you to to figure out how to determine if the value of an int is greater than or less than zero, since you didn't attempt that in this snippet.
this will help you, adopt for your purposes
#include <stdio.h>
int main() {
int a;
int i = 0;
int str_size = 0;
char str[11] = {};
char tmp;
scanf("%d", &a);
while (a) {
str[str_size++] = a % 10 + '0';
a /= 10;
}
str_size--;
while (i < str_size) { // rewind
tmp = str[i];
str[i++] = str[str_size];
str[str_size--] = tmp;
}
printf("%s", str);
return 0;
}

Resources