There comes a time every so often when I find a typo in my source code. I recently found one in the C version of chastelib. I used the opportunity to expand on my existing comments to better explain the purpose of these functions which are used in my chastehex and chastecmp programs.
I am also working on extension libraries to add to chastelib to support future command line utilities I might write, even if I don’t know what tools I will write. I have dreams of making my own small programming language but what I imagine is more complex that I am prepared for at my skill level and lack of free time.
I just finished my Programming 2 class about C++ and I have to say that I still prefer C, even though there are some features of C++ such as function overloading that I find extremely cool.
Anyway, read below this years edition of the 4 functions that make up the core of chastelib, my own standard library I am building.
/*
This file is a library of functions written by Chastity White Rose. The functions are for converting strings into integers and integers into strings.
I did it partly for future programming plans and also because it helped me learn a lot in the process about how pointers work
as well as which features the standard library provides, and which things I need to write my own functions for.
As it turns out, the integer output routines for C are too limited for my tastes. This library corrects this problem.
Using the global variables and functions in this file, integers can be output in bases/radixes 2 to 36
*/
/*
These two lines define a static array with a size big enough to store the digits of an integer, including padding it with extra zeroes.
The integer conversion function always references a pointer to this global string, and this allows other standard library functions
such as printf to display the integers to standard output or even possibly to files.
*/
#define usl 32 /*usl stands for Unsigned String Length*/
char int_string[usl+1]; /*global string which will be used to store string of integers. Size is usl+1 for terminating zero*/
/*radix or base for integer output. 2=binary, 8=octal, 10=decimal, 16=hexadecimal*/
int radix=2;
/*default minimum digits for printing integers*/
int int_width=1;
/*
This function is one that I wrote because the standard library can display integers as decimal, octal, or hexadecimal, but not any other bases(including binary, which is my favorite).
My function corrects this, and in my opinion, such a function should have been part of the standard library, but I'm not complaining because now I have my own, which I can use forever!
More importantly, it can be adapted for any programming language in the world if I learn the basics of that language.
*/
char *intstr(unsigned int i)
{
int width=0;
char *s=int_string+usl;
*s=0;
while(i!=0 || width<int_width)
{
s--;
*s=i%radix;
i/=radix;
if(*s<10){*s+='0';}
else{*s=*s+'A'-10;}
width++;
}
return s;
}
/*
This function prints a string using fwrite.
This algorithm is the best C representation of how my Assembly programs also work.
Its true purpose is to be used in the putint function for conveniently printing integers,
but it can print any valid string.
*/
void putstring(const char *s)
{
int c=0;
const char *p=s;
while(*p++){c++;}
fwrite(s,1,c,stdout);
}
/*
This function uses both intstr and putstring to print an integer in the currently selected radix and width.
*/
void putint(unsigned int i)
{
putstring(intstr(i));
}
/*
This function is my own replacement for the strtol function from the C standard library.
I didn't technically need to make this function because the functions from stdlib.h can already convert strings from bases 2 to 36 into integers.
However, my function is simpler because it only requires 2 arguments instead of three, and it also does not handle negative numbers.
I have never needed negative integers, but if I ever do, I can use the standard functions or write my own in the future.
*/
int strint(const char *s)
{
int i=0;
char c;
if( radix<2 || radix>36 ){printf("Error: radix %i is out of range!\n",radix);}
while( *s == ' ' || *s == '\n' || *s == '\t' ){s++;} /*skip whitespace at beginning*/
while(*s!=0)
{
c=*s;
if( c >= '0' && c <= '9' ){c-='0';}
else if( c >= 'A' && c <= 'Z' ){c-='A';c+=10;}
else if( c >= 'a' && c <= 'z' ){c-='a';c+=10;}
else if( c == ' ' || c == '\n' || c == '\t' ){break;}
else{printf("Error: %c is not an alphanumeric character!\n",c);break;}
if(c>=radix){printf("Error: %c is not a valid character for radix %i\n",*s,radix);break;}
i*=radix;
i+=c;
s++;
}
return i;
}
/*
Those four functions above are the core of chastelib.
While there may be extensions written for specific programs, these functions are essential for absolutely every program I write.
The only reason you would not need them is if you only output numbers in decimal or hexadecimal, because printf in C can do all that just fine.
However, the reason my core functions are superior to printf is that printf and its family of functions require the user to memorize all the arcane symbols for format specifiers.
The core functions are primarily concerned with standard output and the conversion of strings and integers. They do not deal with input from the keyboard or files. A separate extension will be written for my programs that need these features.
*/
Leave a comment