From 102341d7ae8793c29d44fa416d3b5b797d1eca3e Mon Sep 17 00:00:00 2001 From: Clay Smith Date: Tue, 1 Aug 2023 01:09:09 -0500 Subject: First commit --- my_atoi.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 my_atoi.c (limited to 'my_atoi.c') diff --git a/my_atoi.c b/my_atoi.c new file mode 100644 index 0000000..c5b0642 --- /dev/null +++ b/my_atoi.c @@ -0,0 +1,192 @@ +// TODO: add decimal point hex and octal support +// TODO: add limit to maximum imput allowed +#include //printf(), fprintf() +#include //assert() +#include //exit() +#include //_Bool, false, true +#include "my_atoi.h" + +#define ASCIIFIRST 48 +#define ASCIILAST 57 +#define NULL '\0' + +double my_atoi(char* str) +{ + int i = 0, start = 0, base = 10, floatIndex; + double num2Convert = 0; + _Bool boolHex = false, boolOctal = false, boolNegative = false, boolFloat = false, priorZero = false; + +//017 -017 no decimals for hex or octal NULL, -NULL, .NULL, 0xNULL, 0XNULL, -.NULL, -0xNULL, -0XNULL, 0x., -0x., 0X., -0X., -0[8,9,a-f,A-F], xX can only be in the second or third index 8-9, a-f, A-F, -, ., xX octal: - 0-7 decimal: - . 0-9 hex: 0-9 a-f A-F - xX + +if (str[0] == '-') { + boolNegative = 1; + ++start; + ++i; +} + +do { + switch (str[i]) { + case '0': + if (!priorZero) { + priorZero = true; + if (i == 0 || (i == 1 && boolNegative)) { + if (str[i + 1] == NULL) { + return 0; + } else if (str[i + 1] == '.') { + boolFloat = 1; + floatIndex = i = 1; + ++i; + } else { + boolOctal = 1; + ++start; + } + } + } + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + break; + case '8': + case '9': + if (boolOctal) { + fprintf(stderr, "ERROR: %c is an invalid input for octal numbers\n", str[i]); + exit(-1); + } + break; + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + if (!boolHex) { + fprintf(stderr, "ERROR: %c is an invalid input for octal and/or decimal numbers\n", str[i]); + exit(-1); + } + break; + case '.': + if (boolFloat) { + fprintf(stderr, "ERROR: String contains more than one '.'\n"); + exit(-1); + } else if (boolHex || boolOctal) { + fprintf(stderr, "ERROR: Currently not accepting hexidecimal or octal floating point numbers.\n"); + exit(-1); + } else { + boolFloat = 1; + floatIndex = i; + } + break; + case NULL: + if (i == 0 || str[i - 1] == '-' || str[i - 1] == 'x' || str[i - 1] == 'X'){ + fprintf(stderr, "ERROR: Entered an empty number.\n"); + exit(-1); + } + break; + case 'x': + case 'X': + if (i != 1 && i != 2 && str[i - 1] != 0) { + fprintf(stderr, "ERROR: 'x or X' characters can only be included once and must be preceeded by a 0.\n"); + exit(-1); + } + boolOctal = 0; + boolHex = 1; + ++start; + break; + default: + fprintf(stderr, "ERROR: Invalid character included.\n"); + exit(-1); + } + ++i; +} while (str[i] != NULL); //when this is done I will be the number of characters including null termination + + + if (boolHex) { + for (int j = i - 1, multi = 1, base = 16; j > start - 1; multi *= base, --j) { + switch (str[j]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num2Convert += (multi * (str[j] - ASCIIFIRST)); + break; + case 'a': + case 'A': + num2Convert += multi * 10; + break; + case 'b': + case 'B': + num2Convert += multi * 11; + break; + case 'c': + case 'C': + num2Convert += multi * 12; + break; + case 'd': + case 'D': + num2Convert += multi * 13; + break; + case 'e': + case 'E': + num2Convert += multi * 14; + break; + case 'f': + case 'F': + num2Convert += multi * 15; + break; + default: + fprintf(stderr, "ERROR: out of bounds character for hexadecimal. Only use 0-9,Aa-Ff\n"); + } + } + } else if (boolOctal) { + for (int j = i - 1, multi = 1, base = 8; j > start - 1; multi *= base, --j) { + if (str[j] > ASCIILAST - 2) { + fprintf(stderr, "ERROR: out of bounds range for octal number. Only use 0-7.\n"); + } else { + num2Convert += multi * (str[j] - ASCIIFIRST); + } + } + } else if (boolFloat) { + fprintf(stderr, "NEED TO FIGURE OUT HOW TO CONVERT FLOATS STILL\n"); + //count distance from end -1 to floatIndex and take that number and divide it by the appropriate multiple of 10 + //then do the portion to the left of the decimal the exact same as usual + { + double multi = .1; + for (int j = floatIndex + 1, base = 10; j < i; multi /= base, ++j) { + num2Convert += multi * (str[j] - ASCIIFIRST); + } + } + for (int j = floatIndex - 1, multi = 1, base = 10; j >= start; multi *= base, --j) { + num2Convert += multi * (str[j] - ASCIIFIRST); + } + } else { + for (int j = i - 1, multi = 1, base = 10; j >= start; multi *= base, --j) { + num2Convert += multi * (str[j] - ASCIIFIRST); + } + } + + if (boolNegative) { + num2Convert *= -1; + } + + printf("boolHex: %d, boolOctal: %d, boolFloat: %d, boolNegative: %d, \n", boolHex, boolOctal, boolFloat, boolNegative); + + return num2Convert; + +} -- cgit v1.2.1