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';
Related
Background on what the code is supposed to do, vs what I am achieving.
So the dec2bin function is supposed to get the values/numbers decimal from the array dec_nums[]={0, 1, 77, 159, 65530, 987654321};
the function is supposed to convert the value to binary numbers and print it out.
the conversion is done correctly however, it prints the binary backward.
Can someone help me on figuring out what the problem is, or if there is another way to achieve the correct results?
int main() {
int dec_nums[] = {0, 1, 77, 159, 65530, 987654321};
int i;
printf("=== dec2bin ===\n");
for (i = 0; i < sizeof(dec_nums) / sizeof(int); i++)
dec2bin(dec_nums[i]);
return 0;
}
void dec2bin(int num) {
int saveNum = num;
if (saveNum == 0) {
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
} else {
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++) {
number = num % 2;
num = num / 2;
printf("%i", number);
}
printf("\n");
}
}
For bit fiddling unsigned types are preferrable, you avoid any kinds of problems with undefined behaviour due to under-/overflow.
Apart from, you can operate on bit masks:
for(unsigned mask = 1u << sizeof(mask) * CHAR_BIT - 1; mask; mask >>= 1)
{
unsigned bit = (value & mask) != 0;
// print it
}
CHAR_BIT is the value of bits within a char and comes from header limits.h, typically (but not necessarily) it is 8, with typically four bytes for ints you initialise the mask to 1 << 31 and further on shift it downwards until it reaches 1 << 0, i. e. 1, which is the last value yet considered. Yet another shift moves the single bit set out of the mask, so you get 0 and the loop aborts.
Above code will print leading zeros, you might prepend another loop that simply shifts down until the first 1-bit is met if you want to skip them.
This variant starts at most significant bit; by % 2 you always get the least significant bit instead – which is why you got the inverse order.
Side note: Getting length of an array is better done as sizeof(array)/sizeof(*array) – this avoids errors if you need to change the underlying type of the array...
A simple solution would be to write to bits into a char array, starting from the end of the array, the same way that we would do by hand.
Your dec2bin function would become (only minimal changes, with comments for added or changed lines):
void dec2bin(int num)
{
// declare a char array of size number_of_bits_in_an_int + 1 for the terminating null
char bin[sizeof(int) * CHAR_BIT + 1];
char* ix = bin + sizeof(bin) - 1; // make ix point to the last char
*ix-- = '\0'; // and write the terminating null
int saveNum = num;
if (saveNum == 0)
{
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
}
else
{
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++)
{
number = num % 2;
num = num / 2;
*ix-- = '0' + number; // just write the bit representatin
}
printf("%s\n", ix+1); //print the binary representation
}
}
That is enough to get the expected result.
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.
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;
}
I am trying to find a random number that has 1 to max digits (max < 10).
srand((int) time(NULL));
answer = ((rand() % max) + 1);
BUT:
0,...9 is only allowed to be used once.
I have found that waiting for the rand() to create such a number by chance takes too long, so I am assuming there must be a way to create a running total where each time a digit is added a comparison is made.
If you are looking for an integer with n digits drawn from 0 to 9 with no repeats (your question is hard to interpret), then the following will suffice.
The idea is to put all the digits from 0 to 9 in a hat and then draw them out one by one. Append each to the random integer value you're building.
The hat is an array initially set 0 to 9.
To draw a number when the hat has k elements in it, compute a random index j in the range [0..k-1] and get that element from the array. Then copy the last (k-1 th) element down to position j, which "erases" it. The remaining unpicked digits are now in [0..k-2], and you can repeat this process until done.
Appending a digit d to an integer value is the same as saying
val = 10 * val + d
Putting these ideas together, you have the following. Note this allows 0 in the first position, so the result may actually have one less than n digits when printed with no leading zeros.
unsigned random_unrepeated_digits(int n) {
int i, digits[] = { 0,1,2,3,4,5,6,7,8,9 };
unsigned val = 0;
for (i = 0; i < n; i++) {
int k = 10 - i, j = rand() % k;
val = 10 * val + digits[j];
digits[j] = digits[k - 1];
}
return val;
}
You can generate the each digit one by one. First, get a random integer from 0 to 9. For instance, if you get 5, then remove it from the array of all digits:
0 1 2 3 4 6 7 8 9
Next get a random integer from 0 to 8, if you get 8 this time, then the second digit is 9. Remove it and get the next digit repeatedly.
If you need to get 8 digits for instance, In the end you have only 4 digits left, for instance:
3 4 6 9
Then get a random integer from 0 to 3. If for instance, you get 0, then the last digit is 3 and the rest is discarded.
You can shuffle the digits {0, 1, 2, ..., 9}, being careful not to put 0 first, then construct the number from the appropriate number of initial digits. By doing this, while constructing the result as you go, and stopping shuffling once you've fixed the first ndig digits, you end up with code like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
long long rand_digits(int ndig) {
int digits[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
long long res = 0;
for (int i = 0; i < ndig; i++) {
int r = i + rand() % (10 - i - (i == 0));
res = res * 10 + digits[r];
digits[r] = digits[i];
}
return res;
}
int main(int argc, char *argv[]) {
srand((unsigned)time(0));
for (int i = 0; i < 10; i++) {
printf("%-2d: %lld\n", i + 1, rand_digits(i + 1));
}
return 0;
}
You can use array of 10 digits, shuffle them each time and get the N first digits. Pseudo code:
void shuffle(char[] a) {
for(int i=0; i< 10; i++) {
pos = rand() % 10;
swap(a[i], a[pos]);
}
}
int main() {
char arr[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
# it prints endlessly random numbers of random length
while (1) {
shuffle(arr);
int N = rand() % 10 + 1; # how many digits to generate
for (int i=0; i<N; i++) {
printf(arr[i]);
}
}
printf("\n");
}
The possible issue in this way is when '0' comes the first digit, turning the number to gets less number than it is required. But you can add avoiding '0' at first position by fixing 'shuffle'(e.g, check if the first is '0' then generate random pos=rand()%9+1 and then swap(a[0], a[pos]) or getting numbers if you need it.
You could set up a function:
char * randstr(int len)
{
srand(0); //seed the generator
char * str = malloc(len); //allocate exactly len bytes
int i, x; //define some loop variables
char used = 0; //used is to check if the number has already been taken
char num; //a temp value
for (i = 0; i < len; i++)
{ //this loop runs through each character in the string
used = 1;
while (used) //basically, if we already used it, find another
{
used = 0;
num = rand() % 10 + 48; //48 = '8' //returns 0-9
for (x = 0; x < i; x++)
{ //this loop checks to see if its already been used
if (str[x] == num) used = 1;
}
}
}
return str;
}
This will return a char array, but not a null terminated one, though all of the numbers will be in ASCII form. For a null terminated string, simply modify it like so:
char * randstr(int len)
{
srand(0);
char * str = malloc(len + 1);
int i, x;
char used = 0;
char num;
for (i = 0; i < len; i++)
{
used = 1;
while (used)
{
used = 0;
num = rand() % 10 + 48; //48 = '8'
for (x = 0; x < i; x++)
{
if (str[x] == num) used = 1;
}
}
}
str[len - 1] = 0;
return str;
}
Hope this helps.
EDIT:
The way the function works, is it returns a string of size len, using only digits 1-9, with no repeats.
calling randstr(5) could return something like
12345
93751
73485
...
Do note, if there are no more numbers to use, the function will just sit there looping.
Comments are in the first function
Getting a random number of digits would be actually pretty simple. We just want a random number between 1 and 10. Done by
rand() % 10 + 1;
//so lets assign that to an int and call our function
int num = rand() % 10 + 1;
char * str = randstr(num); //assume this is the null terminated one
printf("The number was %s\n", str);
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));