How to grab some digits from a number? - c

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;
}

Related

My decimal to hex conversion function only woks with positive nums

I'm having problems converting negative numbers, from decimal base to hexadecimal base, with the following function:
#include <stdio.h>
int main()
{
int quotient, remainder;
int i, j = 0;
char hexadecimalnum[100];
quotient = -50;
while (quotient != 0)
{
remainder = quotient % 16;
if (remainder < 10)
hexadecimalnum[j++] = 48 + remainder;
else
hexadecimalnum[j++] = 55 + remainder;
quotient = quotient / 16;
}
strrev(hexadecimalnum);
printf("%s", hexadecimalnum);
return 0;
}
For quotient = -50; the correct output should be:
ffffffce
But this function's output is:
.
With positive numbers the output is always correct but with negative numbers not.
I'm having a hard time understanding to why it doesn't work with negative numbers.
Some fixes:
unsigned int quotient - you need to convert -50 to a large hex number in two's complement or you'll get the wrong number of iterations (2) in the loop, instead of 8 as required.
Removal of "magic numbers": '0' + remainder and 'A' + remainder - 10.
Zero initialize hexadecimalnum becaues it needs to be null terminated before printing a string from there. Better yet, add the null termination explicitly.
Use for loops when possible.
Might as well store the characters from the back to front and save the extra call of reversing the string.
Result:
#include <stdio.h>
// 4 bytes*2 = 8 nibbles
#define HEX_STRLEN (sizeof(int)*2)
int main()
{
unsigned int remainder;
int i = 0;
char hex[100];
for(unsigned int q = -50; q!=0; q/=16)
{
remainder = q % 16;
if (remainder < 10)
hex[HEX_STRLEN-i-1] = '0' + remainder;
else
hex[HEX_STRLEN-i-1] = 'A' + remainder - 10;
i++;
}
hex[HEX_STRLEN] = '\0'; // explict null termination
printf("%s\n", hex);
}
(There's lots of improvements than can be made still, this is just to be considered as the first draft.)
You can use printf's format specifier "%08x", then you can print any number in their respective hexadecimal representation.
#include <stdio.h>
void num_to_hex(int a, char *ptr) { snprintf(ptr, 9, "%08x", a); }
int main() {
char hex[10] = {};
num_to_hex(-50, hex);
printf("%s\n", hex);
return 0;
}
Output:
ffffffce

No output shown on problem 8 of project euler

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);
}

C - Distinguishing Between Chars and Digits, then Handling Accordingly

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

How to format output correctly?

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.

Iterating through digits in integer in C

I have an integer like 1191223
and I want to iterate over the digits. I am not sure how to do this in C, is there any easy way to do this?
Thanks.
Forwards, or backwards?
Assuming a positive integer:
unsigned int n = 1191223;
while (n != 0) {
doSomething (n % 10);
n /= 10;
}
…will work smallest to largest, or…
EDIT I'd forgotten all about this non-working solution I had here. Note that Very Smart People™ seem to use the smallest-to-largest iteration consistently (both Linux kernel and GLibC's printf, for example, just iterate backwards) but here's a lousy way to do it if you really don't want to use snprintf for some reason…
int left_to_right (unsigned int n) {
unsigned int digit = 0;
if (0 == n) {
doSomething (0);
} else {
digit = pow(10, 1.0+ floor(log10(n)));
while (digit /= 10) {
doSomething ( (n / digit) % 10 );
}
}
}
I assume that it's very silly to assume that you have log10 and pow but not snprintf, so an alternate plan would be
int left_to_right_fixed_max (unsigned int n) {
unsigned int digit = 1000000000; /* make this very big */
unsigned int n10 = 10 * n;
if (0 == n) {
doSomething (0);
} else {
while (digit > n10) { digit /= 10; }
while (digit /= 10) {
doSomething ( (n / digit) % 10 );
}
}
}
… or, if you really don't have hardware multiply/divide, you can resort to using a table of powers of ten.
int left_to_right (unsigned int n) {
static const unsigned int digit [] =
{ 1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000 /* make this very big */
};
static const unsigned char max_place = 10;
/* length of the above array */
unsigned char decimal;
unsigned char place;
unsigned char significant = 0; /* boolean */
if (0 == n) {
doSomething (0);
} else {
place = max_place;
while (place--) {
decimal = 0;
while (n >= digit[place]) {
decimal++;
n -= digit[place];
}
if (decimal | significant) {
doSomething (decimal);
significant |= decimal;
}
}
}
}
…which I have adapted from http://www.piclist.com/techref/language/ccpp/convertbase.htm into a somewhat more general-purpose version.
In the following I assume you mean decimal digits (base 10). Probably you are able to adapt the solutions to other numeral systems by substituting the 10s.
Note, that the modulo operation is a tricky thing concerning negative operands. Therefore I have chosen the data type to be an unsigned integer.
If you want to process the least significant digit first, you could try the following untested approach:
uint32_t n = 1191223;
do {
uint32_t digit = n%10;
// do something with digit
}
while (n/=10);
If you prefer to walk through the digits starting from the most significant digit, you could try to adapt the following untested code:
uint32_t n = 1191223;
#define MAX_DIGITS 10 // log10((double)UINT32_MAX)+1
uint32_t div = pow(10, MAX_DIGITS);
// skip the leading zero digits
while ( div && !(n/div) ) div/=10;
if ( !div ) div = 10; // allow n being zero
do {
uint32_t digit = (n/div)%10;
// do something with digit
}
while (div/=10);
You want to iterate over base-10 digits, but an integer has no concept of arabic notation and digits. Convert it to a string first:
int i = 1191223;
char buffer[16];
char *j;
snprintf(buffer, 16, "%i", i);
for ( j = buffer; *j; ++j ) { /* digit is in *j - '0' */ }
You can use sprintf() to convert it into a char array, and then iterate through that, like so (untested, just to get you started):
int a = 1191223;
char arr[16];
int rc = sprintf(arr, "%d", a);
if (rc < 0) {
// error
}
for (int i = 0; i < rc; i++) {
printf("digit %d = %d\n", i, arr[i]);
}
void access_digits(int n)
{
int digit;
if (n < 0) n = -n;
do {
digit = n % 10;
/* Here you can do whatever you
want to do with the digit */
} while ((n/=10) > 0);
}
Something like this:
char data[128];
int digits = 1191223;
sprintf(data, "%d", digits);
int length = strlen(data);
for(int i = 0; i < length; i++) {
// iterate through each character representing a digit
}
Notice that if you use an octal number like 0100 you also need to change the sprintf(data, "%d", digits); to sprintf(data, "%o", digits);.
For my purposes the following short code did the trick.
Having a an integer variable the_integer, and an integer variable sum_of_digits initialized. (line 1) You could do the following:
1) Convert the integer variable to a variable of type string with use of the std::to_string(int) function.
2) Iterate of the characters of the resulting string. for(char& c: str::to_string(the_integer))
3) To convert the characters back to integers use c -'0' . For this solution take a look at the discussion in (Convert char to int in C and C++).
4) .. and adding them the digits together: sum_of_digits += c-'0'
*) you can then print your variables: lines 3 and 4.
int the_integer = 123456789; int sum_of_digits;
for (char& c: std::to_string(the_integer)) {sum_of_digits += c-'0';}
std::cout << "Integer: " << the_integer << std::endl;
std::cout << "Sum of Digits << sum_of_digits << std::endl;
Note that std::to_string() has some notes, please consult the c++ references to see if the code is still relevant for your purposes.
A hackish way is to convert this to string (see strtol) and then reconvert this to a number.
you could use something like character you want - '0'
Off the top of my head: "i % 100000", "i % 100000", ...
A recursive solution would let you start from "i%10".

Resources