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

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.

Related

How to see if integer has a specific digit in it in C

I need to build a program, that would write all numbers from 0 to 100, but will place an * instead of any number that contains the digit 3 or can be divided by 3. This is what I have so far. How can I make it work?
#include <stdio.h>
main() {
int i, c;
c = 100;
for (i = 0; i <= c; i++) {
if (i % 3 == 0) {
printf("*");
}
if (i)
printf("%d\n", i);
}
}
place an * instead of any number that contains the digit 3 or can be divided by 3.
OP's code took care of the "can be divided by 3" with i % 3 == 0.
How about a little divide and conquer for the "contains the digit 3"? Put a function in there.
if (contains_the_digit(i, 3) || (i % 3 == 0)) {
printf("*\n");
} else {
printf("%d\n", i);
}
Now what is left is to define contains_the_digit(int i, int digit)
Mathematically (nice and efficient):
bool contains_the_digit_via_math(int i, int digit) {
do {
if (abs(i % 10) == digit) { // Look at the least digit, abs() to handle negative `i`
return true;
}
i /= 10; // Now look at the upper decimal digits
} while (i);
return false;
}
Or textually:
bool contains_the_digit_via_string(int i, int digit) {
char buf[30]; // Something certainly big enough
sprintf(buf, "%d", i);
return strchr(buf, digit + '0') != NULL;
}
Or use your imagination for other ideas.
The key is to take your problems and reduce them to smaller ones with helper functions: divide and conquer.
Concert the number to a string
Replace '3' with '*' within that string
i.e.
int to_be_converted =12345612343242432; // Or summat else
char num[100]; // Should be more than enough
sprintf(num, "%d", to_be_converted);
for (int i =0; num[i]; i++) {
if (num[i] -- '3') num[i] = '*';
}
printf("Here you go %s", num);
That should do the trick
Just ad the bit to go through the numbers and check if divisible by 3. I leave that to the reader.
Seeing you forgot to add the return type int to your int main(), I think this is a good time to learn to write your own function!
In this case, you want a function that can check whether the last digit of a number is a 3 when you represent that number as base-10. That's easy! The function should look like (you need to #include <stdbool.h> at the beginning of your file, too):
bool ends_in_decimal_3(int number) {
// figure out a way to find the difference
// between number, rounded to multiples of 10
// and the original number. If that difference==3,
// then this ends in 3 and you can `return true;`
}
Armed with that function, you can see whether your i itself ends in 3, or whether i/10 ends in 3 and so on. Remembering that division / in C between ints always rounds down is a good trick to do that, and also an important hint on how to implement your rounding in ends_in_decimal_3.

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

C program which is finding "happy" nums recursively

Hello guys i am trying to implement a program which is finding the happy numbers were between two numbers A and B.
Summing the squares of all the digits of the number, we replace the number with the outcome, and repeat the process. If after some steps the result is equal to 1 (and stay there), then we say that the number N is **<happy>**. Conversely, if the process is repeated indefinitely without ever showing the number 1, then we say that the number N is **<sad>**.
For example, the number 7 is happy because the procedure described above leads to the following steps: 7, 49, 97, 130, 10, 1, 1, 1 ... Conversely, the number 42 is sad because the process leads to a infinite sequence 42, 20, 4, 16, 37, 58, 89, 145, 42, 20, 4, 16, 37 ...
I try this right down but i am getting either segm faults or no results.
Thanks in advance.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
printf("%ld %d\n",A,npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == 1 || A[0] == 7)
printf("%c\n",A[0]);
printf("%s\n",A);
return;
}
long sum = 0 ;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = atoi(&A[i]);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Thanks for your time.
by the definition of your program sad numbers will cause your program to run forever
Conversely, if the process is repeated indefinitely
You need to add a stopping condition, like if I have looped for 1000 times, or if you hit a well known non terminating number (like 4) (is there a definite list of these? I dont know)
I find this solution tested and working..
Thanks for your time and I am sorry for my vagueness.
Every advice about this solution would be welcome
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
if (happynum ==1)
printf("%s\n",Ap);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == '3' || A[0] == '6' || A[0] == '9')
{
happynum = 0;
}
else
{
happynum = 1;
}
return;
}
long sum = 0;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = (int)(A[i]-48);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Your code uses some questionable practices. Yoe may be misguided because you are concerned about performance and memory usage.
When you allocate memory for the string, you forget to allocate one character for the null terminator. But you shouldn't be allocating, re-allocating and freeing constantly anyway. Dynamic memory allocation is expensive compared to your other operations.
Your limits are long, which may be a 32-bit or 64-bit signed integer, depending on your platform. The maximum number that can be represented with e 64-bit signed integer is 9,223,372,036,854,775,807. This is a number with 19 digits. Add one for the null terminator and one for a possible minus sign, so that overflow won't hurt, you and use a buffer of 21 chars on the stack.
You probably shouldn't be using strings inthe first place. Use the basic code to extract the digits: Split off the digit by taking the remainder of a division by 10. Then divide by 10 until you get zero. (And if you use strings with a fixed buffer size, as described above, you don't have to calculate the difits separately: sprintf returns the number of characters written to the string.
Your functions shouldn't be recursive. A loop is enough. As pm100 has noted, you need a termination criterion: You must keep track of the numbers that you have already visited. Each recursive call creates a new state; it is easier to keep an array, that can be repeatedly looked at in a loop. When you see a number that you have already seen (other than 1, of course), your number is sad.
Happy and sad numbers have this property that when your sum of squares is a number with a known happiness, the original number has this happiness, too. If you visit a known das number, the original number is sad. If you visit a known happy number, the original number is happy.
The limits of your ranges may ba large, but the sum of square digits is not large; it can be at most the number of digits times 81. In particular:
type max. number number of max. square sum dss
int 2,147,483,647 1,999,999,999 730
uint 4,294,967,295 3,999,999,999 738
long 9,223,372,036,854,775,807 8,999,999,999,999,999,999 1522
ulong 18,446,744,073,709,55,1616 9,999,999,999,999,999,999 1539
That means that when you take the sum of digit squares of an unsigned long, you will get a number that is smaller than 1540. Create an array of 1540 entries and mark all known happy numbers with 1. Then you can reduce your problem to taking the sum of digit squares once and then looking up the happiness of the number in this array.
(You can do the precalculation of the array once when you start the program.)

Trailing Zeros in printf/sprintf

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

Print the digits of a number in reverse order without arrays or functions

As a homework problem, I'm working on reading a decimal int from stdin, converting it to a different base (also provided from stdin) and printing it to the screen.
Here's what I've got so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// keep dividing to find remainders
while (quotient > 0) {
remainder = num % base;
quotient = num / base;
num = quotient;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
}
printf("\n");
return 0;
}
This works great, only that the algorithm this uses calculates the converted numbers from least significant to most significant digit, thus printing it in reverse. So, for example, converting 1020 to hexadecimal ( 0x3FC ) will print CF3.
Is there a trick I could use to reverse these numbers to print in the correct order. I can only use if-else, while, simple math operators and printf()/getchar()/scanf() - no functions, arrays or pointers. thanks.
(removed original part of the post here, since it is not the solution)
Then the only solution I can see is to perform the loop that you have now the number of times that you have digits.
So, first you calculate all digits till you get to the last, and then print it.
Then you take the original value + base and start dividing again till you come to the second "highest value" digit, then print it.
It is a double loop and you calculate everything twice, but you don't use extra storage.
It's a good try, and well phrased question. If only we had more people asking questions in such a clear manner!
The restrictions seem artificial. I guess you haven't learned about functions, arrays, pointers etc., in your class yet, but I think this problem is not meant to be solved elegantly without functions and/or arrays.
Anyway, you can do something like this:
curr := base
pow := 1
while num / curr >= 1 do:
curr := curr * base
pow := pow + 1
while pow >= 1:
pow := pow - 1
print floor(num / base ** pow)
num := mod(num, base ** pow)
Basically, you are calculating how many digits you will need in the first loop, and then printing the digits in the correct order later.
Some specific issues with your code. I understand it's the beginning of a C class, but still, it's better to know of such issues now than to never realize them:
printf("please enter a positive number to convert: ");
You should add an fflush(stdout) after this to make sure the output appears before scanf() is called. By default, stdout is line buffered on many systems, so the prompt may not appear before your program waits for input.
printf("please enter the base to convert to: ");
Same as above.
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
You're assuming ASCII character set. This need not be true. But without arrays or pointers, there's no easy way to print the alphabets corresponding to 10.... Also, your code may print weird characters for base > 36.
You should also be aware that it's very hard to use scanf() safely. Hopefully you will learn better ways of getting input later.
In one loop you can calculate the number of digits and the big_base.
In a second loop you can output the digits starting from the most significant, like this:
n = 1020, 3 hex digits, big_base = 16*16
1st step
1020 / (16*16) = 3
2nd step
n = 1020- 3*(16*16) = 252
252 / (16) = 15, F
3rd step
n = 252 - 15*16 = 12, C
Hey ! I recognize a famous homework I had in first year of my school too (#Epitech students : don't copy/paste the following code, try to come up with your own solution, it's for your own good ^^)
The solution to your problem is to perform the problem in a recursive way :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
Does your homework specifies that it should only work with positives numbers ? If not, it's easy to include the negative numbers handling :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
}
#arno : that's true, because the exemple code is using ASCII table. If we want something trully flexible we need the base in parameter. For example :
>> my_putnbr_base(4242, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
39U
>> my_putnbr_base(42, "0123456789ABCDEF")
2A
this implements the example :
void my_putnbr_base(int num, char *base)
{
int start;
int remainder;
int len;
len = strlen(base);
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % len;
start = (num - remainder) / len;
if (start != 0)
my_putnbr_base(start, base);
printf("%c", base[remainder]);
}
}
I hope it solves your problem !
edit: I didn't read correctly ^^ You are not allowed to use functions, so recursion is out of the question... Here is an interative way, you can put this in a main(). You can improve this code by adding the negative numbers handling and flexible bases, as I showed you :)
int my_putnbr_base_it(int num, int base)
{
unsigned int quotient = 1;
unsigned int remainder;
while ((num / quotient) >= base)
quotient *= base;
while (quotient)
{
if ((remainder = (num / quotient) % base) < 10)
printf("%d", remainder);
else
printf("%c", 55 + remainder);
quotient /= base;
}
return (0);
}
Hope it solves everything now !
You could rewrite the piece of code calculating each number to behave as a state machine. It will start in the initial state and compute the number of digits, then change the state to "print the Nth digit" to print the most significant digit, then change the state to proceed to the less significant digits, etc until it eneters the final state. Running this inside a loop you will output all digits in proper order.
You could use two loops. The first keeps generating powers of the base until it finds a power greater than the input number. The second starts from here (or rather, one power before) and works back to base^0 (i.e. 1) to compute the output digits most significant first.
Untested pseudo-code:
// Determine highest power, don't actually need "power" it's just there for illustration
power = 0;
baseraisedtopower = 1;
while (baseraisedtopower <= input)
{
baseraisedtopower *= base;
power++;
}
// Go back one step, could have saved previous result
baseraisedtopower /= base;
power--;
// Output
while (input > 0)
{
// Integer division, truncate
quotient = input / baseraisedtopower;
printf("%c", quotient + 55);
input -= quotient * baseraisedtopower;
baseraisedtopower /= base;
power--;
}
You can give a try at this approach.
It's more a proof of concept, you'll still need to handle some special case, but, hey, that's your homework :)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
int divider;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// First get the highest divider
divider = base;
while ( num / divider > base ) {
divider *= base;
}
do {
// Get the highest digit
remainder = num / divider;
// And update num accordingly
num -= remainder * divider;
divider /= base;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
} while ( divider );
printf("\n");
return 0;
}
Interesting task, you've got as a homework.
I am a beginner programmer to, and I've tried to resolve this task.
The following code is working (I haven't tested a lot, apparently is working). I am sure it's not the optimal&best solution, but was the only thing I've could come up with. It should work with any base. Unfortunately it won't convert 10->A, 11->B, etc.:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int nr,base,res,tp,tpb,tpbt,r,rnr,lp,lpt,i;
float baset,rt;
/** Read number */
printf("nr=");
scanf("%d",&nr);
/** Read base */
printf("base=");
scanf("%d",&base);
/** Returning result */
res=0;
/** Test if number is positive
and base is bigger than 2 */
if(nr<0||base<2){
/** Error */
res=1;
}
else{
/** Determine how many
digits are necessary */
lp=0;
baset=base;
while(baset>1){
lp++;
baset/=10;
}
/** Determine full power
of 10 when r has length of lp */
tpb=1;
while((lp--)>0){
tpb*=10;
}
/** Power of ten that will be
incremented */
tp=0;
/** Converted number (will be printed
as the result) */
rnr=0;
/** Algorithm */
while(nr>0){
r=nr%base;
nr/=base;
rt=r;
/** Temporary lp for
r */
lpt=0;
while(rt>1){
lpt++;
rt/=10;
}
/** Temporary tpb for
lpt */
tpbt=tpb;
for(i=0;i<lpt;i++){
tpbt/=10;
}
/** Build number */
rnr+=r*pow((double)(tpbt),(double)(tp++));
}
}
/** Show number */
printf("number is: %d \n",rnr);
return (res);
}
Based on what was suggested, the way to tackle this was to keep print the last number and repeat the loop for every digit. I kept track of the print condition by saving the previous quotient and printing when I got to it every time (then reseting the number and starting over), then reset it to the one before. Sounds complicated, but the change to the code was simple. My stop condition for the loop was when I had 2 consecutive prints, since most of the time it would just calculate quotient/remainder and print nothing, and when 2 digits print in a row, it's the last two. Anyway, here's the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, saved, base, remainder;
int quotient, prev_q, stop_q, just_printed;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
saved = num;
remainder = quotient = prev_q = just_printed = 1;
stop_q = 0;
// validate input
if (num <= 0 || base <= 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// divide
while (1) {
remainder = num % base;
quotient = num / base;
num = quotient;
// print if it's the last number and reset num to the next
if (quotient == stop_q) {
if (remainder >= 10) { printf("%c", remainder + 55); }
else { printf("%d", remainder); }
// if 2 consecutive printing occur, this means it's time to end this
if (just_printed) { break; }
// next time print when hitting the previous quotient
stop_q = prev_q;
// reset the number to the original value
num = saved;
just_printed = 1;
} else {
just_printed = 0;
}
prev_q = quotient;
}
printf("\n");
return 0;
}
Thanks to everyone who pitched in!
We could use a recursive function to reverse the order of the digits of a number :
We'll need some mathematical functions from these libraries - stdlib.h and math.h
int reverse(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverse(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
'If statement' is the base case for the recursive function.
'Else statement' may look intimidating at first but it's actually just simple arithmetic. floor(log10(abs(x))) gives us the number of digits of x, so ((x%10)*(pow(10, (floor(log10(abs(x))))))) is just putting the 'ones' place digit of the number to its correct place in accordance with the desired reversed number.
For better comprehension let's take an example, Let 123 be the number we need to reverse. The first thing that the function reverse will do is ask itself the reverse of 12 (reverse(x/10)) and when the function is called for the second time with argument 12 it'll ask itself the reverse of 1, Now this will be the base case for our function. It'll return 1 as abs(1)<=9, Now 2 will be prepended using ((x%10)*(pow(10, (floor(log10(abs(x)))))) it then will return 21 and 3 will be prepended by the same.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int reverse(int x);
int main()
{
int x, revInt;
scanf("%d", &x); // input : 123
revInt = reverse(x);
printf("%d", revInt); // output : 321
return 0;
}

Resources