2 changed files with 262 additions and 0 deletions
@ -0,0 +1,260 @@
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include <ctype.h> |
||||
|
||||
/* THIS IS A WORK IN PROGRESS.
|
||||
* |
||||
* This is my first program in C and I look forward to learning more and making |
||||
* those changes as I go along. Feedback is appreciated, for example -Wall and |
||||
* -pedantic (see Makefile) were very appreciated. |
||||
* |
||||
* I'm not looking for perfection. |
||||
* |
||||
* The goal is to later maybe putting this into an ATTiny or Atmega328 and put |
||||
* it into some hardware. Just for fun with a display and inputs and stuff. |
||||
* |
||||
* What I learned writing this: |
||||
* - Internet searches return pretty unhelpful stuff |
||||
* - ... but I found out that there is something called ispunct, isupp, isalnum |
||||
* and a lot of other helpful functions that are part of the C standard |
||||
* library. If the validation thing even is something I want. |
||||
* - but trying to find out what I wanted about these were harder, |
||||
* then I remember I have manpages installed - but how do I find them? man |
||||
* stdlib.h, stdio.h and string.h didn't have anything, but man ispunct lead |
||||
* me to man ctype.h where I found everything I needed. |
||||
* |
||||
* TODO/Need to look into: |
||||
* - Freeing memory after use |
||||
* - Use valgrind |
||||
* - Look for null pointers and stuff |
||||
* - Read about pointers |
||||
* - Padding for binary number output |
||||
* - Padding for decimal output |
||||
* - Decimal to hex converter |
||||
* - Other things mentioned in the code |
||||
*/ |
||||
|
||||
#define LINE 20 |
||||
|
||||
// declare functions - guess these should go into a header file?
|
||||
// the error messages I got before putting this here were not helpful.
|
||||
char* validate_input(char*); |
||||
char* to_hex(char*); |
||||
int hex_to_decimal(char*, char*, int); |
||||
char* to_binary(unsigned int, char*); |
||||
char* binary_string(char*, char*); |
||||
int binary_to_decimal(char*, char*); |
||||
|
||||
char hex[4]; // 4 characters (ff ff)
|
||||
int bin[8]; // 8 digits (1111 1111)
|
||||
int dec[5]; // 5 digits (65 535)
|
||||
|
||||
int main() { |
||||
char* buffer = malloc(LINE+1); |
||||
char buf2[17]; |
||||
char buf3[LINE+1]; |
||||
int i; |
||||
int ch; |
||||
|
||||
printf("Enter a number and this program will convert the number to decimal, hexadecimal \n"); |
||||
printf("and binary.\n"); |
||||
|
||||
while (1) { |
||||
printf("\n> "); |
||||
|
||||
for (i = 0; (i < LINE) && (( ch = getchar()) != EOF) && (ch !='\n'); i++) |
||||
buffer[i] = ch; |
||||
|
||||
buffer[i] = '\0'; |
||||
int size = i; |
||||
|
||||
if (buffer[0] == '\0') |
||||
break; |
||||
|
||||
//printf("Given string was: '%c'\n", *test);
|
||||
|
||||
char *test = validate_input(buffer); |
||||
int in_decimal; |
||||
char *in_binary; |
||||
|
||||
in_decimal = hex_to_decimal(buffer, buf2, size); |
||||
in_binary = to_binary(in_decimal, buf2); |
||||
printf("%s as hex:\n", buffer); |
||||
printf("decimal> %i\n", in_decimal); |
||||
printf("binary> %s\n", binary_string(in_binary, buf3)); |
||||
printf("\n"); |
||||
|
||||
if (*test == 'd') { |
||||
printf("%s as decimal:\n", buffer); |
||||
in_binary = to_binary(atoi(buffer), buf2); |
||||
printf("hex> \n"); |
||||
printf("binary> %s\n", binary_string(in_binary, buf3)); |
||||
} |
||||
|
||||
if (*test == 'b') { |
||||
printf("%s as binary:\n", buffer); |
||||
int binary_in_decimal = binary_to_decimal(buffer, buf2); |
||||
printf("hex> \n"); // TODO: Convert binary to hex
|
||||
printf("decimal> %i\n", binary_in_decimal); |
||||
} |
||||
|
||||
free(test); |
||||
} |
||||
|
||||
printf("Exiting program.\n"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
char* binary_string(char* in_binary, char* buffer) { |
||||
int j = 0; // for padding
|
||||
for (int i = 0; i < 16; i++) { |
||||
buffer[i] = (int) in_binary[i]; |
||||
} |
||||
buffer[17] = '\0'; |
||||
|
||||
return buffer; |
||||
} |
||||
|
||||
// TODO:
|
||||
//char* to_hex(char* input) {
|
||||
//}
|
||||
|
||||
int hex_to_decimal(char* input, char *buff, int size) { |
||||
char *pbuff = buff; |
||||
int newbuff[8]; |
||||
int newbuff_used; |
||||
|
||||
char *ch = input; |
||||
ch += size; |
||||
|
||||
*pbuff = 1; |
||||
|
||||
// TODO: Shouldn't have to do this. Look into atoi()?
|
||||
// 0=48
|
||||
// a=97
|
||||
for (int i = 0; i < LINE; i++) { |
||||
*ch--; |
||||
if (*ch == '\0') { |
||||
break; |
||||
} |
||||
if (*ch >= 97) { |
||||
int tmp = *ch - 87; |
||||
newbuff[i] = tmp; |
||||
} else { |
||||
newbuff[i] = *ch - 48; |
||||
} |
||||
newbuff_used = i+1; |
||||
} |
||||
|
||||
int result = 0; |
||||
int exp; |
||||
for (int i = 0; i < newbuff_used; i++) { |
||||
exp = i; |
||||
|
||||
while (exp > 0) { |
||||
newbuff[i] *= 16; |
||||
--exp; |
||||
} |
||||
|
||||
result += newbuff[i]; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
char* to_binary(unsigned int input, char *buff) { |
||||
char *pbuff = buff; |
||||
|
||||
int size = 16; |
||||
|
||||
pbuff += size; |
||||
*pbuff-- = '\0'; |
||||
|
||||
for (int i = 0; i < size; i++) { |
||||
*pbuff-- = ((input & 1) == 1) ? '1' : '0'; |
||||
|
||||
input >>= 1; |
||||
|
||||
} |
||||
return pbuff+1; |
||||
} |
||||
|
||||
int binary_to_decimal(char* input, char *buff) { |
||||
char *pbuff = input; |
||||
|
||||
int size = strlen(input); |
||||
printf("size: %i\n", size); |
||||
int result = 0; |
||||
|
||||
pbuff += size; |
||||
int exp = 1; |
||||
|
||||
for (int i = 0; i < size; i++) { |
||||
*pbuff--; |
||||
|
||||
int val = (int) *pbuff; |
||||
val -= 48; // TODO: Shouldn't have to do this. Look into atoi()?
|
||||
|
||||
result += val * exp; |
||||
|
||||
exp *= 2; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
// returns b for binary, h for hex, d for decimal or e for error
|
||||
char* validate_input(char* input) { |
||||
int b_count = 0; // binary
|
||||
int h_count = 0; // hex (hexadecimal)
|
||||
int d_count = 0; // decimal (alphanumerical)
|
||||
int a_count = 0; // letters (alpha)
|
||||
int length = 0; |
||||
|
||||
int i; |
||||
char *ret = malloc(1); |
||||
|
||||
for (i = 0; i < 8; i++) { |
||||
if (input[i] == '\0') { |
||||
printf("\n"); |
||||
break; |
||||
} |
||||
|
||||
if (input[i] == '0' || input[i] == '1') |
||||
b_count++; |
||||
|
||||
if (isdigit(input[i])) |
||||
d_count++; |
||||
|
||||
if (isalpha(input[i])) |
||||
a_count++; |
||||
|
||||
if (isxdigit(input[i])) { |
||||
h_count++; |
||||
} else { |
||||
printf("%c error\n", input[i]); |
||||
ret[0] = 'e'; |
||||
return ret; |
||||
} |
||||
|
||||
length++; |
||||
} |
||||
|
||||
// if it contains letters it's not binary and not a decimal
|
||||
if (a_count == 0) |
||||
ret[0] = 'd'; |
||||
|
||||
// Hex is written in groups of 2, like ff or 0afe, not fad.
|
||||
if (a_count != 0 && length == h_count && (h_count == 2 || h_count == 4)) |
||||
ret[0] = 'h'; |
||||
|
||||
// Binary is written in groups of 2 (or 4), like 10, 11, 1011 and 0100, not 1 or 101.
|
||||
if (a_count == 0 && length == b_count && (b_count % 2 == 0)) |
||||
ret[0] = 'b'; |
||||
|
||||
//printf("%-1c: %d d, %d h, %d b, %d length\n\n", ret[0], d_count, h_count, b_count, length);
|
||||
|
||||
return ret; |
||||
} |
||||
Loading…
Reference in new issue