/* EXERCISE 2-6 */ /* USE THE FUNCTION htol(s) TO CONVERT TWO INPUT STRINGS OF HEX */ /* DIGITS INTO LONG INTEGERS. */ #include <stdio.h> #define MAXLEN 9 void loadnext(void); int loadstr(char s[]); unsigned long htol(char s[]); void ltoh(unsigned long bnum, char s[]); void reverse(char s[]); int atoi(char s[]); unsigned long setbits(unsigned long x, int p, int n, unsigned long y); int c = EOF + 1; int snum; int len, str1_len, error; char string_1[MAXLEN]; char string_2[MAXLEN]; char string_3[MAXLEN]; char string_4[MAXLEN]; char string_res[MAXLEN]; unsigned long lint1; int int2; int int3; unsigned long lint4; unsigned long result; enum boolean {NO, YES}; enum escapes {BELL = '\a', BACKSPACE = '\b', TAB = '\t', NEWLINE = '\n', VTAB = '\v', RETURN = '\r'}; main() { int i; /* LOAD FOUR STRINGS FROM ONE INPUT LINE */ error = NO; for (snum = 1; snum <= 4; ++snum) loadnext(); if (error == NO) { result = setbits(lint1, int2, int3, lint4); ltoh(result, string_res); printf("RESULT: %s\n", string_res); } printf("\nEND OF PROGRAM\n"); return 0; } /* LOADNEXT: LOAD THE NEXT STRING */ void loadnext(void) { if (error == NO) if (snum == 1) len = loadstr(string_1); else if (snum == 2) len = loadstr(string_2); else if (snum == 3) len = loadstr(string_3); else if (snum == 4) len = loadstr(string_4); if (error == NO) if (len == 0) { error = YES; if (snum == 1) printf("FIRST "); else if (snum == 2) printf("SECOND "); else if (snum == 3) printf("THIRD "); else if (snum == 4) printf("FOURTH "); printf("STRING MISSING\n"); } else if (snum == 1) { lint1 = htol(string_1); str1_len = len; } else if (snum == 2) int2 = atoi(string_2); else if (snum == 3) int3 = atoi(string_3); else if (snum == 4) lint4 = htol(string_4); } /* LOADSTR: LOAD THE NEXT NON-BLANK STRING FROM THE INPUT LINE */ int loadstr(char s[]) { int i = 0; int end_string = NO; error = NO; if (c != '\n' && c != EOF) { while (error == NO && end_string == NO && (c = getchar()) != NEWLINE && c != EOF) if (c == ' ' || c == BELL || c == BACKSPACE || c == TAB || c == VTAB || c == RETURN) if (i > 0) end_string = YES; else ; else if (i < MAXLEN - 1) { s[i++] = c; } else { error = YES; printf("\nSTRING IS TOO LONG\n"); } s[i] = '\0'; } return i; } /* HTOL: CONVERT A STRING OF HEX DIGITS TO A LONG INTEGER */ unsigned long htol(char s[]) { unsigned long dec = 0; int i = 0; int n; if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) i = 2; while (error == NO && s[i] != '\0') { if (s[i] >= '0' && s[i] <= '9') n = s[i] - '0'; else if (s[i] >= 'a' && s[i] <= 'f') n = 10 + s[i] - 'a'; else if (s[i] >= 'A' && s[i] <= 'F') n = 10 + s[i] - 'A'; else { error = YES; printf("\nINVALID HEX NUMBER\n"); } if (error == NO) dec = 16 * dec + n; ++i; } return dec; } /* LTOH: CONVERT A LONG INTEGER TO A STRING OF HEX DIGITS */ void ltoh(unsigned long bnum, char s[]) { int i = 0; int n; while (bnum > 0) { n = bnum % 16; if (n > 9) s[i++] = 'A' + n - 10; else s[i++] = '1' + n - 1; bnum = bnum / 16; } while (str1_len > i) s[i++] = '0'; s[i] = '\0'; if (i > 1) reverse(s); } /* REVERSE: REVERSE A CHARACTER STRING */ void reverse(char s[]) { int i, j; char hold; i = 0; while (s[i] != '\0') ++i; j = i - 1; for (i = 0; i < j; ++i) { hold = s[i]; s[i] = s[j]; s[j] = hold; --j; } } /* ATOI: CONVERT A STRING OF DIGITS TO AN INTEGER */ int atoi(char s[]) { int dec = 0; int i = 0; int n; while (error == NO && s[i] != '\0') { if (s[i] >= '0' && s[i] <= '9') n = s[i] - '0'; else { error = YES; printf("\nINVALID DECIMAL NUMBER\n"); } if (error == NO) dec = 10 * dec + n; ++i; } return dec; } /* SETBITS: SET THE n BITS THAT BEGIN IN POSITION p OF x TO THE */ /* RIGHTMOST BITS n BITS OF y. */ unsigned long setbits(unsigned long x, int p, int n, unsigned long y) { if (n > p + 1) n = p + 1; return (unsigned long) /* ZERO THE BITS TO BE REPLACED IN x */ (x & ~((~(~0UL << n)) << (p + 1 - n))) | ((y & ~(~0UL << n)) << (p + 1 - n)); /* ZERO THE LEADING BITS IN y */ /* MOVE THE REST INTO POSITION */ }