Wednesday, May 30, 2012

Learning C with K&R

Recently I have begun learning C using the highly regarded K&R second edition.

I decided to take a break from the Udacity courses, with the intention of returning to finish them later.  I really wanted to get away from Python, which I've been using exclusively for the past 6 months and finally learn my 2nd programming language.

I chose C because it seems to exist at the polar opposite of Python.  It is low level, statically typed, fast and relatively old.  Python is pretty much the opposite of all those things.

I'm really glad I made this choice.  After just a couple chapters I already feel I am learning so much more about programming.  I now have a deeper understanding of just how much Python was taking care of for me in terms of memory management and abstraction.  I definately miss the ease with which I could code in Python, but I think this is an excellent learning experience.

Below is the code for exercise 2-3 in K&R which converts a hexadecimal string into a decimal value.

Codepad


#include <stdio.h>
#include <string.h>
#include <math.h>
int acceptable_input(char s[]);
int acceptable_char(char c);
int htoi(char s[]);
int main(){
    int cycle = 0;
    char text[30];
    int i;
    char c;
    while(cycle < 10){
        cycle++;
        i = 0;
        printf("enter hexademical (0x prefix optional): ");
        while((c = getchar()) != 10){
            text[i] = c;
            i++;
        }
        text[i] = '\0';
        printf("your input: %s\n", text);
        printf("DECIMAL VALUE: %d\n", htoi(text));
    }
    return 0;
}
int htoi(char s[]){
    printf("------------------\n");
    printf("s: %s (before strip)\n", s);
    // strip 0x or 0X
    int haszero = (s[0] == '0');
    char old_s[50];
    strcpy(old_s, s);
    int hasx = (s[1] == 'x' || s[1] == 'X');
    if (haszero && hasx){
        int i;
        for (i = 2; s[i] != '\0'; i++)
            s[i-2] = s[i];
        s[i-2] = '\0';
    }
    printf("s: %s\n", s);
    int okay = acceptable_input(s);
    printf("acceptable string?: %d\n", okay);
    if (okay == 0){
        printf("Input unacceptable.\n");
        return 9999;
    }
    int length = strlen(s);
    printf("length: %d\n", length);
    int x;
    int mult;
    int num;
    int result = 0;
    for(x = 0; x < length; x++) {
        mult = (int)pow(16,length-(x+1));
        num = (int)s[x] - (int)'0';
        if(s[x] == 'a' || s[x] == 'A') num = 10;
        if(s[x] == 'b' || s[x] == 'B') num = 11;
        if(s[x] == 'c' || s[x] == 'C') num = 12;
        if(s[x] == 'd' || s[x] == 'D') num = 13;
        if(s[x] == 'e' || s[x] == 'E') num = 14;
        if(s[x] == 'f' || s[x] == 'F') num = 15;
        printf("char: %c\tnum: %d\tmult: %d\tvalue: %d\n",
            s[x], num, mult, num * mult);
        result = result + num * mult;
    }
    return result;
}
int acceptable_char(char c){
    char good[] = "0123456789abcdefABCDEF";
    int i;
    for(i = 0; good[i] != '\0'; i++){
        if (c == good[i])
            return 1;
    }
    return 0;
}
int acceptable_input(char s[]){
    int i;
    for (i = 0; s[i] != '\0'; i++){
        if(acceptable_char(s[i]) == 0)
            return 0;
    }
    return 1;
}

No comments:

Post a Comment