Kevin De Baerdemaeker

Exercises: The C Programming Language

Modified 2025-09-24

Helpers

int myGetline(char s[], int lim) {
  int c, i;

  for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++) {
    s[i] = c;
  }

  if (c == '\n') {
    s[i] = c;
    ++i;
  }

  s[i] = '\0';
  return i;
}
void reverse(char s[]) {
  int c, i, j;

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

CH3

3-1

You remove the second if, by checking if the v[mid] == x, right before returning -1.

3-2

#include <stdio.h>
#define MAXLEN 1000

<<srcMyGetline>>

void escape(char s[], char t[]) {
    int i, j;

    for(i=0, j=0; t[i] != '\0'; ++i, ++j) {
        switch(t[i]) {
            case('\t'):
                s[j] = '\\';
                s[++j] ='t';
                break;
            case('\b'):
                s[j] = '\\';
                s[++j] ='b';
                break;
            default:
                s[j] = t[i];
                break;
        }
    }
    s[j] = '\0';
}

int main(void) {
    char line[MAXLEN], modline[MAXLEN];

    while(myGetline(line, MAXLEN) > 0) {
        escape(modline, line);
        printf("%s", modline);
    }

    return 0;
}

3-3

#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

#define MAXLEN 1000

<<srcMyGetline>>

bool isValidRange(char begin, char end) {
    return begin < end && ((isdigit(begin) && isdigit(end))
           || (isalpha(begin) && isalpha(end)
           && ((islower(begin) && islower(end))
           || (isupper(begin) && isupper(end)))));
}

void expand(char s[], char t[]) {
    int i, j;

    for(i=0, j=0; t[i] != '\0'; ++i) {
        if(i != 0 && t[i] == '-' && isValidRange(t[i - 1], t[i + 1])) {
            for(char c = t[i - 1] + 1; c < t[i + 1]; ++c) {
                s[j++] = c;
            }
        } else {
            s[j++] = t[i];
        }
    }
    s[j] = '\0';
}

int main(void) {
    char line[MAXLEN], modline[MAXLEN];

    while(myGetline(line, MAXLEN) > 0) {
        expand(modline, line);
        printf("%s", modline);
    }

    return 0;
}

3-4

In two's complement the positive side has 1 extra bit to work with, so when you convert it to a negative number, you get an integer overflow. Using unsigned integers would help.

3-6

#include <stdio.h>
#include <string.h>

#define MAXLEN 1000

<<srcMyGetline>>
<<srcReverse>>

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

    if((sign = n) < 0) { // capture sign
        n = -n;
    }

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

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

    while(i < pad) {
        s[i++] = 'X';
    }

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


int main(void) {
    char line[MAXLEN], modline[MAXLEN];

    int number = 12345;
    itoa(number, line, 10);

    printf("%s\n", line);
    printf("%lu", strlen(line));
    return 0;
}

TODO CH4