[ create a new paste ] login | about

Link: http://codepad.org/AfrN1jHo    [ raw code | output | fork ]

ninwa - C, pasted on Sep 11:
/* The C Programming Language
   My solutions to exercises in chapter 3. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <math.h>

#define __DEBUG__   0
#define SORTED_MAXSIZE  6
#define COUNT_MAXSIZE   3
#define EXPAND_MAXSIZE  1024

#define MAX(x,y) (x>y) ? x : y
#define MIN(x,y) (x<y) ? x : y

enum WHITESPACE{ SPACE = 0, TAB, NEWLINE };


void whitespace_count(char[], int[]);


/* e 3-1 */
int binsearch(int,int[],int);

/* e 3-2 */
void escape(char[], int);
void escape2(char[], int);
void unescape(char[]);

/* e 3-3 */
void expand(char[], char[]);

/* e3-4 */
void reverse(char[]);
void tcpl_itoa(int, char[]);
void my_itoa(int, char[]);

/* e3-5 */
void itob(int, char[], int);

/* e3-6 */
void fitoa(int, char[], int); /* I think I sorta cheated. */

int main(int argc, char* argv[])
{
    int i;
    int somenum = 3123;
    int sorted[SORTED_MAXSIZE] = {0,5,10,15,20,30};
    int count[COUNT_MAXSIZE] = {0};
    int find = 5;

    char escape_me[32] = "This should \n be \t escaped!";

    char expand_me[EXPAND_MAXSIZE] = "-A-Z hi to you sir, 0-9, a-z-";
    char expand_to[EXPAND_MAXSIZE];

    char reverse_me[6] = "Hello";
    char s_tcpl_itoa[32];
    char s_my_itoa[32];
    char s_itob[32];
    char s_fitoa[32];

    tcpl_itoa(somenum, s_tcpl_itoa);
    my_itoa(somenum, s_my_itoa);
    itob(312, s_itob, 2);
    fitoa(312, s_fitoa, 10);

    escape2(escape_me, 32);
    expand(expand_me, expand_to);

    whitespace_count("Counting the whitespace\n in this\t!", count);

    for (i = 0; i < COUNT_MAXSIZE; ++i)
        printf("Whitespace count: %d\n", count[i]);

    printf("Found '5' at index: %d\n", binsearch(find, sorted, SORTED_MAXSIZE));
    printf("Escaped: %s\n", escape_me);
    unescape(escape_me);
    printf("Unescaped: %s\n", escape_me);
    printf("Expand: %s\n", expand_me);
    printf("Expanded to: %s\n", expand_to);

    printf("Sizeof int: %lu\n", sizeof(int));
    printf("Max negative int: %d\n", INT_MAX);

    printf("Reverse of %s\n", reverse_me);
    reverse(reverse_me);
    printf("is: %s\n", reverse_me);
    printf("k&r ITOA: %s\n", s_tcpl_itoa);
    printf("My  ITOA: %s\n", s_my_itoa);
    printf("My itob: %s\n", s_itob);
    printf("fixed-width itoa: %s\n", s_fitoa);
    return 0;
}

void fitoa(int n, char s[], int w)
{
   const char fmt[32] = "%*d";
   sprintf(s, fmt, w, n);
}

void itob(int n, char s[], int b)
{
    int i, x, sign;
    i = sign = 0;

    if(n < 0)
        sign = 1;

    do
    {
        x = n % b;

        if(x > 9)
            s[i++] = x + 'A' - 9;
        else
            s[i++] = x + '0';

    } while ( n /= b );

    if(sign)
        s[i++] = '-';

    s[i] = '\0';
    reverse(s);
}

void reverse(char s[])
{
    int i, j;
    char c;

    for( i = 0, j = strlen(s)-1; i < j; i++, j-- )
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

void my_itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0)
        n = -n;

    i = 0;
    do {
        s[i++] = n % 10 + '0';
    } while (n /= 10);

    if (sign < 0)
        s[i++] = '-';

    s[i] = '\0';
    reverse(s);
}

void tcpl_itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0)
        n = -n;

    i = 0;
    do {
        s[i++] = n % 10 + '0';
    } while ((n /= 10) > 0);

    if (sign < 0)
        s[i++] = '-';

    s[i] = '\0';
    reverse(s);
}

void whitespace_count(char s[], int count[])
{
    int i;

    for( i = 0; i < strlen(s); ++i ){
        switch(s[i]) {
        case ' ':
            count[SPACE]++;
            break;
        case '\n':
            count[NEWLINE]++;
            break;
        case '\t':
            count[TAB]++;
            break;
        default:
            break;
        }
    }
}

/* Searches for value x in v[] where n is highest element to
   be searched. */
int binsearch(int x, int v[], int n)
{
    int mid;
    int low = 0;
    int high = n - 1;
    mid = (low+high)/2;

    while( low <= high && x != v[mid]){
        if(__DEBUG__)
            printf("low:%d, high:%d, mid:%d, x:%d\n", low, high, mid, x);

        if( x > v[mid] )
            low = mid+1;
        else
            high = mid+1;

        mid = (low+high)/2;
    }

    if( x == v[mid])
        return mid;

    return -1;
}

/*re-wrote escape to work in-place */
void escape2(char s[], int bufsize)
{
    int i, j, count = -2;
    int len = strlen(s)-1;

    /* Scan over string once counting
       our characters to expand */
    for( i = 0; i < len; ++i)
        if(s[i] == '\t' || s[i] == '\n')
            count+=2;

    if( count > bufsize)
        return;

    s[len+count+1] = '\0';
    for( i = len, j=len+count; i >= 0; i--, j--)
        if(s[i] == '\t' &&  j-1 >= 0){
            s[j] = 't';
            s[j-1] = '\\';
            j--;
        }
        else if( s[i] == '\n' && j-1 >= 0){
            s[j] = 'n';
            s[j-1] = '\\';
            j--;
        }
        else
            s[j] = s[i];
}

/* converts escaped characters into actual visible character representations
   in the string, a newline becomes literal '\n' */
void escape(char s[], int bufsize)
{
    int i, j;
    int len = strlen(s);
    char tmp[SHRT_MAX];

    if(bufsize < len)
        return;

    for( i = j = 0; i < len; ++i ){
        switch(s[i]){
            case '\n':
                if( j+2 < bufsize ){
                    tmp[j] = '\\';
                    tmp[j+1] = 'n';
                    j+=2;
                }
                break;

            case '\t':
                if( j+2 < bufsize ){
                    tmp[j] = '\\';
                    tmp[j+1] = 't';
                    j+=2;
                }
                break;

            default:
                tmp[j] = s[i];
                j++;
                break;
        }
    }

    s[j+1] = '\0';
    strcpy(s, tmp);
}

/* converts all literal "\n" and "\t" in a string to actual newlines and tabs. */
void unescape(char s[])
{
    int i, j;
    int len = strlen(s)-1;
    char tmp[SHRT_MAX];

    for( i = j = 0; i < len; ++i) {
        if( s[i] == '\\'  && i+1 < len){
            if (s[i+1] == 'n')
                tmp[j] = '\n';
            else if(s[i+1] == 't')
                tmp[j] = '\t';
            j++;
            i++;
        } else {
            tmp[j] = s[i];
            j++;
        }
    }

    tmp[j] = '\0';
    strcpy(s, tmp);
}

/* All constructs such as a-z, A-Z, and 0-9 present in s1 are expanded into
   the full character set in s2, e.g. a-Z becomes abcdef...xyz */
void expand(char s1[], char s2[])
{
    int i, min, max, p1, p2;
    p1 = p2 = 0;

    while (s1[p1] != '\0'){
        if(s1[p1] == '-' && p1-1 != -1 && s1[p1+1] != '\0'){
            p2--;
            max = MAX((int)s1[p1-1],(int)s1[p1+1]);
            min = MIN((int)s1[p1-1],(int)s1[p1+1]);
            for( i=min; i < max; i++ ){
                s2[p2] = (char)i;
                p2++;
            }
        } else {
            s2[p2] = s1[p1];
            p2++;
        }

        p1++;
    }

    s2[p2] = '\0';
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Whitespace count: 4
Whitespace count: 1
Whitespace count: 1
Found '5' at index: 1
Escaped: This should \n be \t escaped!
Unescaped: This should 
 be 	 escaped
Expand: -A-Z hi to you sir, 0-9, a-z-
Expanded to: -ABCDEFGHIJKLMNOPQRSTUVWXYZ hi to you sir, 0123456789, abcdefghijklmnopqrstuvwxyz-
Sizeof int: 4
Max negative int: 2147483647
Reverse of Hello
is: olleH
k&r ITOA: 3123
My  ITOA: 3123
My itob: 100111000
fixed-width itoa:        312


Create a new paste based on this one


Comments: