[SOLVED] Convert a number into base 8(octal) in C Program
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
A loop would involve some way to sense how to come of the loop and proceed with next instruction. Also in this case how not to lose the result of the %8 operation.
In pseudo-code, it might be:
Define a string T to hold the result and initialise it.
While p >= 0
q=p%8;
T=q+T;
p=p-q;
Loop back
Yes i tested it with 1953 and it gave me 3641, so it works. The problem is I was using 1953 as a prototype for the program so as such it cannot output a variable with five digits. I see what the others meant about loops it is difficult to create this program without loops. I suppose the loop would accept the value of p, append it to q,r,s,t,u.. and so forth until it reached the number of digits that was input. Like so:
Code:
#include <stdio.h>
int main(void)
{
int p, q, r, s, t;
printf("Enter a number:");
scanf("%d", &p);
while(p >= 0 && a)//where a is some code for the number of digits input by the user
{
q = p % 8;//or
r = q % 8;//something
s = r % 8;//similar
//so on until the loop terminates
}
return 0;
}
Could you specify what you are saying about a string T and why i need to decrement p by q.
No need to use loops unless you want to make the program generic as to the type of the value you wish to display. For integers, the size is fixed for any given platform, so you can simply perform the required number of steps inline. Some compilers may optimize the code that way anyway. For most Linux platforms, an int is 32 bits, so you would need to use 11 digits. When displaying data in octal or hex, it is not uncommon to display all digits, even the leading zeroes, so you can probably ignore testing for zero as an intermediate value.
Masks and shifts can also be used in place of the modulus' and divisions. An exercise for the reader...
I corrected a mistake. It should be p=(p-q)/8 and not just p=p-q
**************************************
p=1953.
T="" /* an empty string */
while p>= 0.
..
First time, p=1953 (greater than zero).
So q=p%8. ie. q="1" (modulo or reminder portion)
T=q+T so T="1"+"" = "1" p=(p-q)/8 /* corrected */
So p = (1953-1)/8 = 244.
p=244 (greater than zero)
q=p%8. ie q="4"
T=q+T="4"&"1"="41" p=(p-q)/8 /* corrected */
So p = (244-4)/8 = 30.
p=30 (greater than zero)
q=p%8 .ie q="6"
T="6"&"41" = "641" p=(p-q)/8 /* corrected */
So p = (30-6)/8 = 3.
p=3
q=p%8. So q=3
T="3"&"641" = "3641"
p=(3-6)/8
Since now P is less than zero, the while condition is not true and so the loop is terminated leaving "3641" as the result in T.
**************************************
Now try it starting with p=4095 and then p=4096 and you will see how the value of p determines the number of iterations.
#include <stdio.h>
int main(void)
{
int p, q;
T = "";//error here how do i declare an empty string?
printf("Enter a value: ");
scanf("%d", &p);
while ( p > 0 && p < 32767)
{
q = p % 8;
T = "";
p = (p - q) / 8;
}
printf("%5d\n", T);
return 0;
}
@theNbomr The shift operator is marked fourteen chapters ahead
A string in C is just a char array with a zero byte at the end of it.
Declaring a char array is easy. The tricky part is that this method of converting to base 8 produces the digits in reverse sequence, so we need to use the buffer backwards.
Code:
#include <stdio.h>
int main(void)
{
int p, q;
char T[6]; /* 5 digits, plus terminating zero */
int n = sizeof(T); /* index for working backward through buffer */
T[--n] = 0; /* Store the terminating 0 */
printf("Enter a value: ");
scanf("%d", &p);
if ( p > 32767 )
{
printf("%d is too big.\n", p);
exit(1);
}
do
{
q = p % 8;
T[--n] = '0' + q; /* Store this digit */
p = p / 8;
} while ( p > 0 );
printf("%5s\n", T+n);
return 0;
}
Comparing to parts of your program:
Quote:
while ( p > 0 && p < 32767)
1) By checking for p>0 at the top of the loop, you get a wrong result for the case where p is initially 0. You want to go through the loop once for that case. I achieved that by moving the while keyword to the bottom of the loop (in C, you use the keyword do at the top of the loop when you want to move the while to the bottom of the loop).
2) The error check for out of range value is best done separately so you can display a meaningful error message.
Originally you said:
Quote:
The program must have an output of five digits regardless of whether the output is five digits or not.
The %5 in the printf makes it take five positions, but not five digits. Controlling the loop with p>0 gives you the minimum number of digits the number needs.
In my version, if you wanted the same number of digits regardless of the value of the initial number, you could control the loop with n>0 instead of p>0.
If you use n>0 instead of p>0 then there was no need to move the while to the bottom of the loop. It would work just as well at the top.
Quote:
printf("%5d\n", T);
That d is incorrect, because you want to print a string, not a decimal number.
If you control the loop in my version with n>0 instead of p>0, then the T would be correct. But controlling the loop with p>0 meant we have filled only a variable amount at the end of the string, so I needed T+n in my version of the printf.
This problem is one that has a more elegant solution with a recursive function, rather than a loop. So you should understand that version as well:
Code:
#include <stdio.h>
/* This function prints the value in base 8 using the specified number of digits */
void print_base_8( int value, int digits )
{
if ( digits > 1 )
print_base_8( value/8, digits - 1 );
printf( "%d", value % 8 );
}
int main(void)
{
int p;
printf("Enter a value: ");
scanf("%d", &p);
if ( p > 32767 )
{
printf("%d is too big.\n", p);
exit(1);
}
print_base_8( p, 5 );
printf("\n");
return 0;
}
The recursive function ends by printing the last digit of the base 8 representation of its input. But first it recursively uses itself to print all but the last digit.
If you wanted to print with a varying number of digits, the code would be even simpler: Leave out everything about digits and use value>0 instead of digits>1 to test the need for further recursion.
Thank you all for your valuable input, I see that i have a lot to learn yet. The question was given to me before i learnt loops, recursive functions, empty strings and the shift operator. So you can imagine how difficult it was.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.