I cannot seem to get my output to work correctly. I want to make it so that the last remainder in parenthesis is lined up perfectly in a column following the first line's spacing. I have most of the output right except for this last part and it has to be exactly the way my professor wants it.
The best I've been able to come up with is EDITED:
Marcus Lorenzana
314156 = 19634 * 16 + 12 (C)
19634 = 1227 * 16 + 2 (2)
1227 = 76 * 16 + 11 (B)
76 = 4 * 16 + 12 (C)
4 = 0 * 16 + 4 (4)
0x4CB2C
This is the output I want:
Marcus Lorenzana
314156 = 19634 * 16 + 12 (C)
19634 = 1227 * 16 + 2 (2)
1227 = 76 * 16 + 11 (B)
76 = 4 * 16 + 12 (C)
4 = 0 * 16 + 4 (4)
0x4CB2C
But as you can see it the output is not exactly correct.
Here is my program EDITED:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER 50
static int base = 16;
int main(int argc, char * argv[]) {
printf("Marcus Lorenzana\n");
if (argc == 2) {
char hexstr[] = "0123456789ABCDEF";
int i = 0;
long long oldresult;
int remainder;
char remainders[BUFFER];
char w_num[BUFFER];
long long value = atoll(argv[1]);
//Get width of original number for formatting purposes
int vwidth = strlen(argv[1]);
char oldwidth[BUFFER];
//Convert the decimal to hexadecimal
while(value != 0) {
oldresult=value;
remainder = value%base;
value = value/base;
//Store the remainder in an array for later use
remainders[i]=hexstr[remainder];
char line[BUFFER];
//Get length of line for formatting purposes
int w = sprintf(line,"%*lld = %-*lld * %2d + %2d", \
vwidth,oldresult,vwidth,value,base,remainder);
printf("%s (%c)\n", line,hexstr[remainder]);
i++;
}
//Print the the hexadecimal number
int x = i;
printf("0x");
while(x > 0) {
printf("%c",remainders[--x]);
}
printf("\n");
} else {
printf("Error: Wrong arguments\n");
return 1;
}
return 0;
}
Modify based on your code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER 50
static int base = 16;
int main(int argc, char * argv[]) {
printf("Marcus Lorenzana\n");
if (argc == 2) {
char hexstr[] = "0123456789ABCDEF";
int i = 0;
long long oldresult;
int remainder;
char remainders[BUFFER];
char w_num[BUFFER];
long long value = atoll(argv[1]);
//Get width of original number for formatting purposes
int vwidth = strlen(argv[1]);
char oldwidth[BUFFER];
int wMax = 0;
//Convert the decimal to hexadecimal
while(value != 0) {
oldresult=value;
remainder = value%base;
value = value/base;
//Store the remainder in an array for later use
remainders[i]=hexstr[remainder];
char line[BUFFER];
//Get length of line for formatting purposes
int w = sprintf(line,"%*lld = %-lld * %2d + %-2d", \
vwidth,oldresult,value,base,remainder);
wMax = w > wMax ? w:wMax;
printf("%s %*s(%c)\n", line,wMax-w,"",hexstr[remainder]);
i++;
}
//Print the the hexadecimal number
int x = i;
printf("0x");
while(x > 0) {
printf("%c",remainders[--x]);
}
printf("\n");
} else {
printf("Error: Wrong arguments\n");
return 1;
}
return 0;
}
Your idea to print the right-hand side to a temporary string is good, but for the output you want, you should just print the stuff to thr right of the equals sign to that string. Also, because you don't want the operands lined up, strip all formatting information, i.e. the widths, from the string.
snprintf(line, BUFFER, "%lld * %d + %d", value, base, remainder);
printf("%*lld = %*s (%c)\n", vwidth, oldresult,
-(vwidth + 10), line, hexstr[remainder]);
The width of the rhs is calculated based on the initial length of the number, vwidth plus two times two for the numbers plus two times three for the operands with surrounding spaces. The width has to be negative, because you want the RHS to be left-aligned and passed with spaces to the right.
If you let printf do the padding, there's no need to store the string length from the sprintf call, w.
Related
I am doing an IBAN validation in C. For this I have a char* which is something like '2012129431327715102998'.
Now I want to check the IBAN by taken the value modulo 97.
So I want to do 2012129431327715102998 % 97.
I have already tried to convert the char* with strtoull but this gives me an out-of-range error. So my question is: How can I convert this char* to a number where I can do a modulo calculation? Thanks in advance
You can write a custom function for this. Applying the modulo operator on partial sums, you can convert a number of arbitrary length:
#include <stdio.h>
int mod97(const char *s) {
int res = 0;
while (*s >= '0' && *s <= '9') {
res = (res * 10 + (*s++ - '0')) % 97;
}
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
printf("%s -> %d\n", argv[i], mod97(argv[i]));
}
return 0;
}
Output:
./mod97 2012129431327715102998
2012129431327715102998 -> 53
This method is simpler and more generic than the one described in the wiki article: computing the modulo 97 of a large number can be achieved by splitting the number in chunks of 9 digits and combining the modulo of these chunks. This splitting is specific to 97 and works because 1000000000 % 97 == 1. The above method works for any modulo value up to INT_MAX / 10.
A simple way without using additional library is to remember that mathematically: mod(a*b, c) == mod(b * mod(a, c), c). So you can process the number in chunks:
// suitable for a 32 bits system, can use 8 for a 64 bits one
#define NB 4
/*********************
* Initial is a string containin only digits representing an arbitrary large number
* div in a number < 10000 (because NB is 4)
* ******************/
int large_mod(char *initial, int div) {
char old[1 + (NB * 2)] = ""; // enough room for a remainder and next chunk
long val;
for (unsigned i=0; i<strlen(initial); i+= NB) {
strncat(old, initial + i, NB); // add the new chunk
val = atol(old) % div; // compute the remainder
sprintf(old, "%ld", val); // keep it for next chunk
// printf("%ld ", val); // uncomment for debugging
}
return (int) val;
}
For 2012129431327715102998 % 97, it gives as expected 53.
This is problem 8 of project euler.
I don't understand why no output is shown. Please don't write direct solution, I just wan't to know where my logic is wrong.
#include <stdio.h>
int main() {
//code
char a[1001]='7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450';
int p,i=0,m;
for(p=1;i<13;i++)p=p*((int)a[i]-48);m=p;printf("%d %d\n",m,p);
for(;i<1001&&a[i]!='\0';i++)
{
p=p/((int)(a[i-13]-48));
p=p*((int)(a[i]-48));
if(m<p)m=p;
}
printf("%d\n",m);
return 0;
}
There are some errors in the posted code, both syntactic and logical.
As already noted, you should use double quotes for the string literal. You could also write it splitted in different lines, the compiler will concatenate all the chuncks and add the \0 terminator.
const char *digits = "73167176531330624919225119674426574742355349194934"
// ...
"71636269561882670428252483600823257530420752963450";
The type int may be too small to represent the value of the product. The Standard only guarantees it to be capable of representing numbers up to 32767 and even a 32-bit (common this days) int can't store 913. I'd suggest using a long long and more meaningful names, e.g.:
#define MAX_ADJACENT_DIGITS 13
// ...
long long product = 0, max_product = 0;
int n_digits = 0;
The error in your algorithm is that it doesn't consider what happens when a digit is zero. An integer division by zero could lead to a runtime error, and besides that, all the products of the nearby digits are equal to zero.
Consider this modified version:
For every character in the string, from the first up to the one which is equal to '\0'
If it's equal to '0' (note the single quotes and the use of the actual char, not a "magic" number)
reset product and n_digits.
Skip the rest of the loop body (continue;).
If it's the first digit of a group of adjacent digits (n_digits == 0)
than product is equal to that digit and we can increase n_digits.
Continue with the next digit.
Here we can update the product (product *= digits[i] - '0';) and increase n_digits.
If we have exceeded the maximum number of adjacent digits
remove the oldest one (product /= digits[i - MAX_ADJACENT_DIGITS] - '0';) from the product and reset n_digits to the maximum.
Update the maximum value of the products, if the current product is bigger.
Following those steps, your program should find the sub-sequence of digits "5576689664895" and output their product.
You have wrong quotes in the initializer of char a[1001] - single quotes are for a character constant, use double quotes for a string literal. And get a better compilation environment - one which warns about such mistakes.
Then, the idea of removing the thirteenth-to-last factor from the current product seems clever at first sight, but it breaks if the digit is zero and you try to divide by it.
you have to change char a[1001] = '123'; to char a[] = "123"; then run it.here is the code
#include <stdio.h>
int main() {
//code
//' ' is used for single character, " " is for string.
char a[]="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int p, i=0, m;
for(p=1;i<13;i++)
{
p = p * ( (int)a[i] - 48);
m = p;
printf("%d %d\n", m, p);
}
for( ; i < (1001 && a[i]!='\0'); i++)
{
p= p / ((int)(a[i-13] - 48));
p= p * ((int)(a[i] - 48));
if(m < p)
m = p;
}
printf("%d\n",m);
return 0;
}
output -:
7 7
21 21
126 126
882 882
882 882
6174 6174
37044 37044
185220 185220
555660 555660
555660 555660
5000940 5000940
5000940
This is my approach to the solution of euler #8. It first uses the strok(3) function to separate the complete string into pieces separated by 0 chars. Then it slides a window of length n over the separated strings (strings of length less than n cannot get enough digits to form a product without involving a 0 so they are discarded.
We then construct the first product by multiplying the first set of n digits. Once it is set, the window is sliced, by multiplying the product by the next digit and dividing the product by the last digit in a queue, pointed by p and q. Products are compared with the maximum and in case they are larger, the position of the match and the new value of the product are stored.
At the end, the substring is printed, starting at the stored position, the index is printed and the product.
The program accepts the options -n and -v:
-n number allows to specify a different number (defaults to 13, as euler #8 indicates)
-v produces more output, indicating at each step the string to be tested, and the products involved.
To compile the program, just:
cc -o 8 8.c
and to run it, just execute 8 at the command line.
If you don't want to see at the solution, don't continue reading.
8.c
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#define FLAG_VERBOSE (1 << 0)
int flags = 0;
int n = 13;
char N[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
int main(int argc, char **argv)
{
int opt;
while ((opt = getopt(argc, argv, "n:v")) != EOF) {
switch (opt) {
case 'n':
if (sscanf(optarg, "%d", &n) != 1) {
fprintf(stderr,
"invalid number: %s\n",
optarg);
}
break;
case 'v':
flags |= FLAG_VERBOSE;
break;
} /* switch */
} /* while */
if (flags & FLAG_VERBOSE) {
printf( "n = %d;\n"
"N = \"%s\"\n",
n, N);
}
char *p, *res = NULL;
unsigned long long res_prod = 0;
for (p = strtok(N, "0"); p; p = strtok(NULL, "0")) {
if (strlen(p) < n) continue;
char *q = p;
unsigned long long prod = 1LL;
int i;
for (i = 0; i < n; i++) { /* initial product */
prod *= *p++ - '0';
}
for(;;) {
int larger = prod > res_prod;
if (flags & FLAG_VERBOSE)
printf("Trying %.*s ==> %llu%s\n",
n, q, prod,
larger ? " !" : "");
if (larger) {
res = q; res_prod = prod;
}
if (!*p) break;
prod /= *q++ - '0';
prod *= *p++ - '0';
}
}
if (res) {
int pos = res - N;
printf("Largest product at position %d (%s%.*s%s): %llu\n",
pos,
pos ? "..." : "", n, res,
pos < sizeof N - 1 - n ? "..." : "",
res_prod);
} else {
printf("No solution found\n");
}
}
You can solve this with a sliding window approach. First grow the window to size 13 and reset the window every time you hit a '0'.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(){
const char a[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
uint64_t prod = 1;
uint64_t m = 0;
size_t count = 0;
for (size_t i = 0; i < sizeof(a) - 1; ++i) {
prod *= a[i] - '0';
if (prod == 0) {
prod = 1;
count = 0;
} else {
if (count++ >= 13) {
prod /= a[i - 13] - '0';
}
if ((count >= 13) && (prod > m)) m = prod;
}
}
printf("max = %"PRIu64"\n", m);
}
I am writing a program that converts user input to either
ASCII values or binary values. If the string contains letters,
each letter should be converted to ASCII. Strings of numbers will
be converted to binary value of entire string. If both letters and
numbers are entered, each letter will be converted to ASCII and the numbers can/will only be separated by letters, for example "32" will print the binary value "00100000", but "3a2" should be converted to "00000011", "97", "00000010".
The way the program is currently written, strings of numbers convert to binary perfectly. However, strings of letters add a decimal "0" to the end. The output converts each letter to its ASCII value, then converts the "0" to binary. I am unsure as to where this "0" is coming from. Additionally, strings beginning
and ending with digits (for example "6j3") will print the ASCII value of j, then the binary value of "6", skipping the "3" entirely and printing the "j" before the "6". I would like to print each ASCII/binary value in the exact order of the user input.
I am posting my entire code for any necessary clarification, but I believe the issue is in the determineChars() function. I am also looking to use the char* letters and char* numbers functions to efficiently handle the appropriate data and store the final num[] and let[] arrays, but I am unsure of how to do this.
I am quite a beginner to C, so excuse the messiness. Corrections, as well as any further optimizations would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#define EIGHT_BITS 255
#define SIXTEEN_BITS 65535
#define THIRTY_TWO_BITS 4294967295UL
#define SIXTY_FOUR_BITS 18446744073709551615ULL
// defined in case of booleans
typedef enum { false, true } bool;
// GET # OF ELEMENTS IN STRING
size_t getSize(char* input) {
size_t size;
size = strlen(input);
printf("Number of Characters..... %d", size);
//printf("\n----------------------------------");
return size;
}
// DETERMINE NUMBER OF BITS TO OUTPUT
int getBitLength(unsigned long long d) {
int l;
if (d <= EIGHT_BITS) {
l = 8;
}
else if (d > EIGHT_BITS && d <= SIXTEEN_BITS) {
l = 16;
}
else if (d > SIXTEEN_BITS && d <= THIRTY_TWO_BITS) {
l = 32;
}
else if (d > THIRTY_TWO_BITS && d <= SIXTY_FOUR_BITS) {
l = 64;
}
printf("\nBits..................... %d", l);
return l;
}
// CONVERT INPUT TO BINARY VALUE
void convertToBinary(char* input) {
static int b[64];
int i, j, length, r;
unsigned long long decimal;
char* pEnd;
// converts input to ull
decimal = strtoull(input, &pEnd, 0);
printf("\n\n---------------- %I64u ------------------", decimal);
printf("\nULL...................... %I64u", decimal);
length = getBitLength(decimal);
// creates array
for (i = 0; i < length; i++) {
r = decimal % 2;
decimal /= 2;
b[i] = r;
}
// reverses array for binary value
printf("\nBinary Value............. ");
for (j = length - 1; j >= 0; j--) {
printf("%d", b[j]);
}
}
char* numbers(char* input) {
char* num = (char*) malloc(sizeof(char) * 25);
return num;
}
char* letters(char* input) {
char* let = (char*) malloc(sizeof(char) * 25);
return let;
}
void determineChars(char* input) {
int i;
char* num = numbers(input);
char* let = letters(input);
size_t inputSize = getSize(input);
// FOR EACH CHARACTER IN INPUT
for (i = 0; i < inputSize; i++) {
if (isdigit(input[i])) {
// stores number values from input into separate array
num[i] = input[i];
printf("\nNumbers: %c", num[i]);
}
if (!isdigit(input[i])) {
// stores letter values from input into separate array
let[i] = input[i];
printf("\nLetters: %c", let[i]);
// prints separator line + ASCII value
printf("\n\n---------------- %c ------------------", let[i]);
printf("\nASCII Value of %c......... %d", let[i], let[i]);
// removes char from input array
input[i] = ' ';
}
}
// char array must consist of digits only
convertToBinary(num);
}
int main() {
// GET INPUT
char input[50];
scanf("%s", input);
determineChars(input);
return 0;
}
I would like to print each ASCII/binary value in the exact order of the user input.
In that case, you would have to restructure your code a bit. This is because if the input contains only digits you will have to print binary and alternate being chars and digits if the string contains both. I have tried to do this with the following code, cleaned it up a bit, removed the warnings and memory leaks.
See if this is what you want:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#define EIGHT_BITS 255
#define SIXTEEN_BITS 65535
#define THIRTY_TWO_BITS 4294967295UL
#define SIXTY_FOUR_BITS 18446744073709551615ULL
// GET # OF ELEMENTS IN STRING
size_t getSize(char* input) {
size_t size;
size = strlen(input);
printf("Number of Characters..... %d\n", size);
//printf("\n----------------------------------");
return size;
}
// DETERMINE NUMBER OF BITS TO OUTPUT
int getBitLength(unsigned long long d) {
int l;
if (d <= EIGHT_BITS) {
l = 8;
}
else if (d > EIGHT_BITS && d <= SIXTEEN_BITS) {
l = 16;
}
else if (d > SIXTEEN_BITS && d <= THIRTY_TWO_BITS) {
l = 32;
}
else if (d > THIRTY_TWO_BITS && d <= SIXTY_FOUR_BITS) {
l = 64;
}
printf("\nBits..................... %d", l);
return l;
}
// CONVERT INPUT TO BINARY VALUE
void convertToBinary(char* input) {
static int b[64];
int i, j, length, r;
unsigned long long decimal;
char* pEnd;
// converts input to ull
decimal = strtoull(input, &pEnd, 0);
printf("\n---------------- %I64u ------------------", decimal);
printf("\nULL...................... %I64u", decimal);
length = getBitLength(decimal);
// creates array
for (i = 0; i < length; i++) {
r = decimal % 2;
decimal /= 2;
b[i] = r;
}
// reverses array for binary value
printf("\nBinary Value............. ");
for (j = length - 1; j >= 0; j--) {
printf("%d", b[j]);
}
printf("\n");
}
void determineChars(char* input) {
int i;
long ret;
char* ptr;
char c;
size_t inputSize = getSize(input);
ret = strtol(input, &ptr, 10);
if((ret == 0) || ((strlen(ptr) != 0) && (strlen(input) != strlen(ptr))))
{
for (i = 0; i < inputSize; i++) {
if (isdigit(input[i])) {
c = input[i];
printf("\nNumber: %c", c);
convertToBinary(&c);
}
if (!isdigit(input[i])) {
// stores letter values from input into separate array
printf("\nLetter: %c", input[i]);
// prints separator line + ASCII value
printf("\n---------------- %c ------------------\n", input[i]);
printf("ASCII Value of %c......... %d\n", input[i], input[i]);
// removes char from input array
}
}
}
else
convertToBinary(input);
}
int main() {
// GET INPUT
char input[50];
scanf("%s", input);
determineChars(input);
}
I also tried out the test cases you mentioned in the question along with few others and it seems to work fine.
32
Number of Characters..... 2
---------------- 32 ------------------
ULL...................... 32
Bits..................... 8
Binary Value............. 00100000
3a2
Number of Characters..... 3
Number: 3
---------------- 3 ------------------
ULL...................... 3
Bits..................... 8
Binary Value............. 00000011
Letter: a
---------------- a ------------------
ASCII Value of a......... 97
Number: 2
---------------- 2 ------------------
ULL...................... 2
Bits..................... 8
Binary Value............. 00000010
6j3
Number of Characters..... 3
Number: 6
---------------- 6 ------------------
ULL...................... 6
Bits..................... 8
Binary Value............. 00000110
Letter: j
---------------- j ------------------
ASCII Value of j......... 106
Number: 3
---------------- 3 ------------------
ULL...................... 3
Bits..................... 8
Binary Value............. 00000011
Let us say we have the following number.
Number = 2001000200030
How can I grab the first digit and store it to a variable? Then
grab the next four digits and store them to another variable?
Then the next four digits ...
So the output should be like this.
first = 2;
firstfour = 0010
secondfour = 0020
thirdfour = 0030
Thank you and I appreciate your time.
Why use strings when you can stick with processing numbers? You can split by digits using modulo and division in powers of 10.
#include <stdio.h>
int main(void) {
long long number = 2001000200030LL;
/* Find power of 10 for top digit */
long long currentDigit = 1LL;
while((currentDigit * 10LL) < number) currentDigit *= 10LL;
printf("First digit = %lld\n", number / currentDigit);
number %= currentDigit;
/* Read off groups of four digits */
while(currentDigit >= 10000LL)
{
long long nextFour;
currentDigit /= 10000LL;
nextFour = number / currentDigit;
number %= currentDigit;
printf("Next four = %04lld\n", nextFour);
}
/* Output any remaining digits not covered by a group of four */
if (currentDigit > 1LL)
{
printf("Remaining digits = ");
for(currentDigit /= 10LL; currentDigit > 1LL; currentDigit /= 10LL)
{
printf("%lld", (number / currentDigit) % 10LL);
}
printf("%lld\n", number % 10LL);
}
return 0;
}
Numbers are stored on the computer in binary, because of this an integer has no capacity to distinguish individual digits.
Convert the number to a string and extract the parts you need. You can also convert each part back into a number if needed. (There are probably prettier ways of extracting parts of the string)
Also this code is for this contrived example, if the integer is unknown, this code cannot safely make the assumptions it does.
long long number = 2001000200030LL;
// convert number to string
char string[64];
sprintf(string, "%lld", number);
// access individual digits
string[0] (first digit)
string[1] (second digit)
// copy first four digits into an int
char firstFour[5]
memcpy(firstFour, string, 4)
firstFour[4] = "\0"; // null terminate
int firstFourInt = atoi(firstFour);
// copy second four digits into an int
char secondFour[5]
memcpy(secondFour, string + 4, 4)
secondFour[4] = "\0"; // null terminate
int secondFourInt = atoi(secondFour);
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int main(void){
int64_t number = 2001000200030LL;
char data[24];
char digit[5] ={0}, *p;
int len, r;
len=sprintf(data, "%lld", number);
p = data;
r = len % 4;
if(r){
strncpy(digit, p, r);
printf("%s\n", digit);
len -= r;
p += r;
}
while(len!=0){
strncpy(digit, p, 4);
printf("%s\n", digit);
len -= 4;
p += 4;
}
return 0;
}
/* output
2
0010
0020
0030
*/
case of the number was a string, and output to string.
#include <stdio.h>
#include <string.h>
int main(void){
char number[] = "2005001000200";
char mode[2]={0};
char red[5]={0};
char green[5]={0};
char blue[5]={0};
strncpy(mode , &number[0], 1);
strncpy(red , &number[1], 4);
strncpy(green, &number[5], 4);
strncpy(blue , &number[9], 4);
printf("Mode = %s\n" , mode);
printf("Red = %s\n" , red);
printf("Green = %s\n", green);
printf("Blue = %s\n" , blue);
return 0;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a printf converter to print in binary format?
Still learning C and I was wondering:
Given a number, is it possible to do something like the following?
char a = 5;
printf("binary representation of a = %b",a);
> 101
Or would i have to write my own method to do the transformation to binary?
There is no direct way (i.e. using printf or another standard library function) to print it. You will have to write your own function.
/* This code has an obvious bug and another non-obvious one :) */
void printbits(unsigned char v) {
for (; v; v >>= 1) putchar('0' + (v & 1));
}
If you're using terminal, you can use control codes to print out bytes in natural order:
void printbits(unsigned char v) {
printf("%*s", (int)ceil(log2(v)) + 1, "");
for (; v; v >>= 1) printf("\x1b[2D%c",'0' + (v & 1));
}
Based on dirkgently's answer, but fixing his two bugs, and always printing a fixed number of digits:
void printbits(unsigned char v) {
int i; // for C89 compatability
for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}
Yes (write your own), something like the following complete function.
#include <stdio.h> /* only needed for the printf() in main(). */
#include <string.h>
/* Create a string of binary digits based on the input value.
Input:
val: value to convert.
buff: buffer to write to must be >= sz+1 chars.
sz: size of buffer.
Returns address of string or NULL if not enough space provided.
*/
static char *binrep (unsigned int val, char *buff, int sz) {
char *pbuff = buff;
/* Must be able to store one character at least. */
if (sz < 1) return NULL;
/* Special case for zero to ensure some output. */
if (val == 0) {
*pbuff++ = '0';
*pbuff = '\0';
return buff;
}
/* Work from the end of the buffer back. */
pbuff += sz;
*pbuff-- = '\0';
/* For each bit (going backwards) store character. */
while (val != 0) {
if (sz-- == 0) return NULL;
*pbuff-- = ((val & 1) == 1) ? '1' : '0';
/* Get next bit. */
val >>= 1;
}
return pbuff+1;
}
Add this main to the end of it to see it in operation:
#define SZ 32
int main(int argc, char *argv[]) {
int i;
int n;
char buff[SZ+1];
/* Process all arguments, outputting their binary. */
for (i = 1; i < argc; i++) {
n = atoi (argv[i]);
printf("[%3d] %9d -> %s (from '%s')\n", i, n,
binrep(n,buff,SZ), argv[i]);
}
return 0;
}
Run it with "progname 0 7 12 52 123" to get:
[ 1] 0 -> 0 (from '0')
[ 2] 7 -> 111 (from '7')
[ 3] 12 -> 1100 (from '12')
[ 4] 52 -> 110100 (from '52')
[ 5] 123 -> 1111011 (from '123')
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
void displayBinary(int n)
{
char bistr[1000];
itoa(n,bistr,2); //2 means binary u can convert n upto base 36
printf("%s",bistr);
}
int main()
{
int n;
cin>>n;
displayBinary(n);
getch();
return 0;
}
Use a lookup table, like:
char *table[16] = {"0000", "0001", .... "1111"};
then print each nibble like this
printf("%s%s", table[a / 0x10], table[a % 0x10]);
Surely you can use just one table, but it will be marginally faster and too big.
There is no direct format specifier for this in the C language. Although I wrote this quick python snippet to help you understand the process step by step to roll your own.
#!/usr/bin/python
dec = input("Enter a decimal number to convert: ")
base = 2
solution = ""
while dec >= base:
solution = str(dec%base) + solution
dec = dec/base
if dec > 0:
solution = str(dec) + solution
print solution
Explained:
dec = input("Enter a decimal number to convert: ") - prompt the user for numerical input (there are multiple ways to do this in C via scanf for example)
base = 2 - specify our base is 2 (binary)
solution = "" - create an empty string in which we will concatenate our solution
while dec >= base: - while our number is bigger than the base entered
solution = str(dec%base) + solution - get the modulus of the number to the base, and add it to the beginning of our string (we must add numbers right to left using division and remainder method). the str() function converts the result of the operation to a string. You cannot concatenate integers with strings in python without a type conversion.
dec = dec/base - divide the decimal number by the base in preperation to take the next modulo
if dec > 0:
solution = str(dec) + solution - if anything is left over, add it to the beginning (this will be 1, if anything)
print solution - print the final number
This code should handle your needs up to 64 bits.
char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so); // version without fill
#define width 64
char* pBin(long int x,char *so)
{
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{ // fill in array from right to left
s[i--]=(x & 1) ? '1':'0'; // determine bit
x>>=1; // shift right 1 bit
} while( x > 0);
i++; // point to last valid character
sprintf(so,"%s",s+i); // stick it in the temp string string
return so;
}
char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{
s[i--]=(x & 1) ? '1':'0';
x>>=1; // shift right 1 bit
} while( x > 0);
while(i>=0) s[i--]=fillChar; // fill with fillChar
sprintf(so,"%s",s);
return so;
}
void test()
{
char so[width+1]; // working buffer for pBin
long int val=1;
do
{
printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,0));
val*=11; // generate test data
} while (val < 100000000);
}
Output:
00000001 = 0x000001 = 0b00000000000000000000000000000001
00000011 = 0x00000b = 0b00000000000000000000000000001011
00000121 = 0x000079 = 0b00000000000000000000000001111001
00001331 = 0x000533 = 0b00000000000000000000010100110011
00014641 = 0x003931 = 0b00000000000000000011100100110001
00161051 = 0x02751b = 0b00000000000000100111010100011011
01771561 = 0x1b0829 = 0b00000000000110110000100000101001
19487171 = 0x12959c3 = 0b00000001001010010101100111000011
You have to write your own transformation. Only decimal, hex and octal numbers are supported with format specifiers.