Mathematics 1201: Programming in C Solutions to Homework Assignment #8 Prof. Wickerhauser Exercise 4 of Chapter 8, p. 218. Program: #include #include int main(void) { int Ch; int Upper=0, Lower=0, Numeric=0, Blank=0, Tab=0, Newline=0, Other=0; while ( (Ch=getchar()) != EOF ) { if( isupper(Ch) ) ++Upper; else /* not an upper case letter */ if( islower(Ch) ) ++Lower; else /* not an upper or lower case letter */ if( isdigit(Ch) ) ++Numeric; else /* not a letter or a number */ switch(Ch){ /* special cases: */ case ' ': ++Blank; break; case '\t': ++Tab; break; case '\n': ++Newline; break; default: ++Other; } } printf("Upper\tLower\tNumeric\tBlank\tTab\tNewline\tOther\n"); printf("-----\t-----\t-------\t-----\t---\t-------\t-----\n"); printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t\n", Upper, Lower, Numeric, Blank, Tab, Newline, Other ); return 0; } Exercises 8 of Chapter 8, p. 219. /* The following routines do no checking whatsoever. It is the programmer's responsibility to insure that the input and output arrays are distinct and large enough. */ char * strcat( char *Lhs, const char *Rhs ) /* (a) */ { int i, j; i = 0; while( Lhs[i] ) ++i; /* advance to the terminating 0 of Lhs[] */ j = 0; while( Rhs[j] ) Lhs[i++] = Rhs[j++]; /* concatenate to terminating 0 of Rhs[] */ Lhs[i] = 0; /* Write a terminating 0 to Lhs[] */ return Lhs; } char * strncpy( char *Lhs, const char *Rhs, int N ) /* (b) */ { int i; /* copy no more than N characters, and only copy non-0s from Rhs[]: */ for( i=0; i #include #include #include #include #include #define BASE_MAX 36 /* Digits are 10 numbers + 26 letters */ static const char digits[] = { /* 36 symbols are available for digits */ "0123456789abcdefghijklmnopqrstuvwxyz" }; static const char ndigs[BASE_MAX+1] = { /* Assume 32-bit long integers */ 0, 0, /* base 0 or base 1 are silly */ 33,21,17,14,13,12, 11, /* base 8 */ 11, 10, /* base 10 */ 10,9,9,9,9, 9, /* base 16 */ 8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7 }; /* bases 17 to 36 */ static unsigned int /* local utility for strtol() below */ StrToUL( const char *s, const char **endptr, int base ) { /* convert string to unsigned long */ const char *sc, *sd; const char *s1, *s2; char sign; ptrdiff_t n; unsigned long int x, y; for(sc=s; isspace(*sc); sc++) /* advance past leading spaces */ ; sign = (*sc=='-' || *sc=='+') ? *sc++ : '+'; /* '+' if no sign */ if ( base<0 || base==1 || BASE_MAX < base ) { /* silly base */ if(endptr) *endptr = (char *)s; return 0; } else if(base) { /* strip 0x or 0X */ if( base==16 && *sc=='0' && (sc[1]=='x' || sc[1]=='X') ) sc += 2; } else if(*sc !='0') base = 10; else if( sc[1]=='x' || sc[1]=='X' ) { base = 16; sc += 2; } else base = 8; for(s1=sc; *sc=='0'; ++sc) ; /* strip leading zeroes */ x = 0; /* Read chars until the first non-digit: */ for( s2=sc; (sd = memchr(digits, tolower(*sc), base)) != NULL; ++sc ) { y = x; /* to check for overflows */ x = x*base + (sd-digits); /* accumulate digits */ } if(s1==sc) { if(endptr) *endptr = (char *)s; return 0; } n = sc - s2 - ndigs[base]; /* non-sign digits read, less most */ if ( n>0 || x < x-sc[-1] || (x-sc[-1])/base != y ) { /* overflow! */ errno = ERANGE; /* Say ``number is out of range'' */ x = ULONG_MAX; /* ...and return ``infinity'' */ } if(sign=='-') x = -x; /* adjust the sign */ if(endptr) *endptr = (char *)sc; /* pointer to the next character */ return x; } long int strtol( const char *NumStr, char **EndPtr, int Base ) { /* convert string to long, with checking */ const char *sc; unsigned long x; for(sc=NumStr; isspace(*sc); sc++) ; /* advance past leading spaces */ x = StrToUL(NumStr, EndPtr, Base); if(*sc=='-' && x<=LONG_MAX) { /* negative number overflowed */ errno = ERANGE; /* Say: ``number out of range'' */ return LONG_MIN; /* ... and return ``- infinity'' */ } else if(*sc != '-' && x>LONG_MAX) { /* positive number overflowed */ errno = ERANGE; /* Say: ``number out of range'' */ return LONG_MAX; /* ... and return ``+ infinity'' */ } else return (long)x; /* OK: no overflows */ } Exercise 12 of Chapter 8, pp. 218--219: Program: #include void SkipLine( void ) { int Ch; while( (Ch=getchar()) != EOF && Ch != '\n') ; } main(void) { int I; I = getchar(); printf("First character, line 1: %c\n", I); SkipLine(); I = getchar(); printf("First character, line 2: %c\n", I); return(0); } Output: % cc ch8ex12.c % a.out < ch8ex10-input First character, line 1: H First character, line 2: B Exercise 10 of Chapter 8, pp. 218--219: Program: #include int ReadLine( char *Str, unsigned int N) { int Ch, i; if(Str==0) return 1; /* Indicates `bad Str' */ if(N==0) { *Str = 0; /* Terminate Str[] immediately */ return 2; /* Indicates `bad N' */ } while( (Ch=getchar()) != EOF ) if(Ch=='\n') { *Str = 0; /* Terminate with NULL, not newline */ return 0; /* Indicates `everything went OK' */ } else if( --N ) /* Haven't run out of N yet... */ *Str++ = Ch; /* Write Ch to Str[] and advance */ else { *Str = 0; /* Terminate Str[] */ return 3; /* Indicates `ran out of N before \n' */ } *Str = 0; /* Terminate Str[] */ return 4; /* Indicates `hit EOF before \n' */ } main(void) { char Line[9]; int err; err = ReadLine(Line, 9); printf("%s(%d)\n", Line, err); err = ReadLine(Line, 9); printf("%s(%d)\n", Line, err); err = ReadLine(Line, 9); printf("%s(%d)\n", Line, err); err = ReadLine(Line, 9); printf("%s(%d)\n", Line, err); return(0); } Output: % cc ch8ex10.c % a.out < ch8ex10-input How now,(0) Brown co(3) .(0) (4) % cat ch8ex10-input How now, Brown cow.