/* Copyright (C) 2021 Gentoo-libre Install
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see .
*/
#include
#include
#include
#define DEFAULT_SIZE 40
//powq(): square roots
unsigned long long powq(int number, int power)
{
unsigned long long result = 1;//result int, 1 by default
if (!power){return 1;}//if to the power of 0, return 1
while(power)//loop until all powers have been calculated
{
result *= number;//in the end result=number*number*number*etc until power is reached
--power;//--power since a power has been calculated
}
return result;
}
//itoh(): Converts integer to hexadecimal with the division algorithm and shows working. Requires length of result string.
void itoh(char s[], char *result, int length)
{
if (s[0] == '\0'){result[0] = 'E'; result[1] = '\0'; return;}//catch case of blank input
if (s[0] == '0' && s[1] == '\0'){printf("0\t| 0\n"); result[0] = '0'; result[1] = '\0'; return;}//catch case of 0 input
int power = 0; //int to store the power.
while(s[power] != '\0'){++power;}//increment power for however many non-null chars in the string.
--power;//The correct power is actually one less than above returns
int i = 0;//counter int
unsigned long long integer = 0;//where the converted int is stored
while (s[i] != '\0')//convert the string of decimal numbers into a long long int
{
if (s[i] >= '0' && s[i] <= '9'){integer += ((s[i] - '0') * powq(10,power));}//integer = integer + ([char converted to number] * (10^[position of number in string]))
++i;
--power;//Deincrement the power. E.g. ([charvalue]*(10^3))+([nextcharvalue]*(10^2)) etc
}
i = 0;
while (integer)
{
switch (integer % 8)
{
case 0:
result[i] = '0';
break;
case 1:
result[i] = '1';
break;
case 2:
result[i] = '2';
break;
case 3:
result[i] = '3';
break;
case 4:
result[i] = '4';
break;
case 5:
result[i] = '5';
break;
case 6:
result[i] = '6';
break;
case 7:
result[i] = '7';
break;
default:
printf("What just occured is meant to be impossible to happen...\n"); exit(1);
break;
}
printf("%llu\t| %c\n", integer, result[i]);
integer /= 8;
++i;
if (i > length-1)
{
result[0] = 'E'; result[1] = '\0';
return;
}
}
result[i] = '\0';//terminate result with null char
char c;
int j = i-1;//i-1 is the first character at the end of the string
//the string needs to be reversed, for the result to be correct.
for(i=0; i < j; ++i, --j)
{
c = result[j];
result[j] = result[i];
result[i] = c;
}
}
int main(int argc, char *argv[])
{
char input[DEFAULT_SIZE];//input string is DEFAULT_SIZE in length
//result string
char *result = malloc(DEFAULT_SIZE*sizeof(char));
if (!result){printf("Malloc failed!\n"); return 1;}
result[DEFAULT_SIZE-1]='\0';//add null terminating char
if (!argv[1]){goto stdinMode;}
if (argv[1][1] == '-')
{
printf("Usage (stdin mode): %s\n", argv[0]);
printf("Ctrl+D to exit\n");
printf("Usage (cli args mode): %s [decnum]\n", argv[0]);
printf("Converts decimal number to octal via the division algorithm.\n");
printf("Licence: GPLv3\n");
return 0;
}
//strip out invalid chars from the input string
int a,q;//counter variables
for (a=0; argv[1][a] != '\0'; ++a)
{
if ((argv[1][a] < '0')||(argv[1][a] > '9'))//if argv[1][i] is a character to remove....
{
q=a;
while(argv[1][q] != '\0'){argv[1][q++] = argv[1][q+1];}//shift all characters above left, overwriting the character
--a;//deincrement a, since the string was just shrunk by one and the one just above could indeed be a matching char
}
}
itoh(argv[1], result, DEFAULT_SIZE-1);
printf("%s\n",result);//print string with all leading 0's
free(result);
return 0;
stdinMode: ;
int i;
nextnum: i=0;
char *character = fgets(input, DEFAULT_SIZE, stdin);
if (!character){free(result); exit(0);}//exit if EOF (fgets() returns -1 on EOF or error)
character = strstr(input,"\n");//try to find the newline in the input so it can be overwritten
if (!character){printf("Input too long\n"); while(getchar() != '\n'); goto nextnum;}//if more than 40 chars were read, input was too long
character = '\0'; //overwrite newline with null char
//strip out invalid chars from the input string
int j;//another counter variable
for (i=0; input[i] != '\0'; ++i)
{
if ((input[i] < '0')||(input[i] > '9'))//if input[i] is an invalid character
{
j=i;
while(input[j] != '\0'){input[j++] = input[j+1];}//shift all characters above left, overwriting the character
--i;//deincrement i, since the string was just shrunk by one and the one just above could indeed be a matching char
}
}
itoh(input, result, DEFAULT_SIZE-1);
printf("Result: 0o%s\n", result);
goto nextnum;
//this wont be reached, but included anyway in case the above goto is removed
free(result);
return 0;
}