/* 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 */
}