Rewrite appropriate programs from earlier chapters and exercises with pointers instead of array indexing. Good possibilities include getline (Chapters 1 and 4), atoi , itoa , and their variants (Chapters 2, 3, and 4), reverse (Chapter 3), and strindex and getop (Chapter 4).
Solution by Gregory Pietsch
/* Gregory Pietsch ex. 5-6 dated 2001-01-29 */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/* getline: get line into s, return length */
int getline(char *s, int lim)
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
*p++ = c;
if (c == '\n')
*p++ = c;
*p = '\0';
return (int)(p - s);
}
/* atoi: convert s to an integer
*
* Here's the easy way:
* int atoi(char *s){return (int)strtoul(s, NULL, 10);}
* But I'll behave...
*/
int atoi(char *s)
{
int n, sign;
while (isspace(*s))
s++;
sign = (*s == '+' || *s == '-') ? ((*s++ == '+') ? 1 : -1) : 1;
for (n = 0; isdigit(*s); s++)
n = (n * 10) + (*s - '0'); /* note to language lawyers --
* the digits are in consecutive
* order in the character set
* C90 5.2.1
*/
return sign * n;
}
/* Shamelessly copied from my 4-12 answer
itoa() is non-standard, but defined on p.64 as having this prototype:
void itoa(int n, char s[])
Instead of this, I thought I'd use a different prototype (one I got from
the library manual of one of my compilers) since it includes all of the
above:
char *itoa(int value, char *digits, int base);
Description: The itoa() function converts an integer value into an
ASCII string of digits. The base argument specifies the number base for
the conversion. The base must be a value in the range [2..36], where 2
is binary, 8 is octal, 10 is decimal, and 16 is hexadecimal. The buffer
pointed to by digits must be large enough to hold the ASCII string of
digits plus a terminating null character. The maximum amount of buffer
space used is the precision of an int in bits + 2 (one for the sign and
one for the terminating null).
Returns: digits, or NULL if error.
*/
char *utoa(unsigned value, char *digits, int base)
{
char *s, *p;
s = "0123456789abcdefghijklmnopqrstuvwxyz"; /* don't care if s is in
* read-only memory
*/
if (base == 0)
base = 10;
if (digits == NULL || base < 2 || base > 36)
return NULL;
if (value < (unsigned) base) {
digits[0] = s[value];
digits[1] = '\0';
} else {
for (p = utoa(value / ((unsigned)base), digits, base);
*p;
p++);
utoa( value % ((unsigned)base), p, base);
}
return digits;
}
char *itoa(int value, char *digits, int base)
{
char *d;
unsigned u; /* assume unsigned is big enough to hold all the
* unsigned values -x could possibly be -- don't
* know how well this assumption holds on the
* DeathStation 9000, so beware of nasal demons
*/
d = digits;
if (base == 0)
base = 10;
if (digits == NULL || base < 2 || base > 36)
return NULL;
if (value < 0) {
*d++ = '-';
u = -((unsigned)value);
} else
u = value;
utoa(u, d, base);
return digits;
}
/* reverse, shamelessly copied from my 4-13 answer */
static void swap(char *a, char *b, size_t n)
{
while (n--) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
a++;
b++;
}
}
void my_memrev(char *s, size_t n)
{
switch (n) {
case 0:
case 1:
break;
case 2:
case 3:
swap(s, s + n - 1, 1);
break;
default:
my_memrev(s, n / 2);
my_memrev(s + ((n + 1) / 2), n / 2);
swap(s, s + ((n + 1) / 2), n / 2);
break;
}
}
void reverse(char *s)
{
char *p;
for (p = s; *p; p++)
;
my_memrev(s, (size_t)(p - s));
}
/* strindex: return index of t in s, -1 if not found */
/* needed strchr(), so here it is: */
static char *strchr(char *s, int c)
{
char ch = c;
for ( ; *s != ch; ++s)
if (*s == '\0')
return NULL;
return s;
}
int strindex(char *s, char *t)
{
char *u, *v, *w;
if (*t == '\0')
return 0;
for (u = s; (u = strchr(u, *t)) != NULL; ++u) {
for (v = u, w = t; ; )
if (*++w == '\0')
return (int)(u - s);
else if (*++v != *w)
break;
}
return -1;
}
/* getop */
#define NUMBER '0' /* from Chapter 4 */
int getop(char *s)
{
int c;
while ((*s = c = getch()) == ' ' || c == '\t')
;
*(s + 1) = '\0';
if (!isdigit(c) && c != '.')
return c; /* not a number */
if (isdigit(c)) /* collect integer part */
while (isdigit(*++s = c = getch()))
;
if (c == '.') /* collect fraction part */
while (isdigit(*++s = c = getch()))
;
*++s = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
/* Is there any more? */
Category 0 Solution by Jesus Alvarez
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define STR_MAX 10000
#define BUFSIZE 100
#define NUMBER '0'
char *my_getline (char *, int);
char *itoa (int, char *);
int atoi (char *);
char *strrev (char *);
int strindex (char *, char *);
int getop (char *);
int getch (void);
void ungetch (int);
int main(int argc, char *argv[])
{
int num;
char ss1[STR_MAX];
char ss2[STR_MAX];
char atoi_buf[STR_MAX];
char itoa_buf[STR_MAX];
int type;
char s[BUFSIZE];
printf (">>> Please enter a number: ");
my_getline(atoi_buf, STR_MAX);
num = atoi(atoi_buf);
printf ("\natoi: str: %s, int: %d\n", atoi_buf, num);
printf ("itoa: int: %d, str: %s\n\n", num, itoa(num, itoa_buf));
printf (">>> Enter string 1: ");
my_getline(ss1,STR_MAX);
printf (">>> Enter string 2: ");
my_getline(ss2,STR_MAX);
printf ("\nThe reverse of string 1: %s\n", strrev(ss1));
printf ("The reverse of string 2: %s\n", strrev(ss2));
num = strindex(ss1, ss2);
if (num == -1) {
printf("\nThe substring (string 2) was not found in the ");
printf("base string (string 1).\n\n");
} else {
printf("\nThe substring was found in the base string, ");
printf("starting at position %d.\n\n", num);
}
printf (">>> Please enter a simple equation (parsing example using getop()).\n");
printf (">>> Example: 100+1039.238-acd\n");
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
printf ("Found a number: %s\n", s);
break;
case '+':
printf ("Found \'+\'\n");
break;
case '\n':
printf ("Found Line Break.\n");
break;
default:
printf ("Found something else: %s\n", s);
break;
}
}
return 0;
}
char *my_getline(char *str, int str_max)
{
char c;
/*
* A local variable to perform arithmetic on so that 'str' points to
* the correct location when it is passed back to the caller.
*/
char *s1 = str;
while ((c = getchar()) != EOF && c != '\n' && str_max-- > 0 ) {
*s1++ = c;
}
if (*s1 == '\n') {
*s1++ = c;
}
*s1 = '\0';
return str;
}
char *itoa(int num, char *str)
{
char *ls = str;
do
{
*ls++ = num % 10 + '0';
} while ((num /= 10) > 0);
strrev(str);
return str;
}
int atoi(char *str)
{
int n, sign;
while (isspace(*str)) {
str++;
}
sign = (*str == '-') ? -1 : 1;
if (*str == '+' || *str == '-') {
str++;
}
for (n = 0; isdigit(*str); str++) {
n = 10 * n + (*str - '0');
}
return n * sign;
}
char *strrev(char *str)
{
int i;
char c;
char *lp1 = str; /* The start of str. */
char *lp2 = str; /* The end of str, for incrementing. */
char *lp3 = str; /* The end of str, for reference. */
i = strlen(str)-1;
lp2 += i;
lp3 += i;
do
{
c = *lp1;
*lp1++ = *lp2;
*lp2-- = c;
} while ((i -= 2) > 0);
*++lp3 = '\0';
return str;
}
int strindex(char *s, char *t)
{
int i, j;
char *sb = s;
char *ss = s;
char *tb = t;
for (i = 0; *sb != '\0'; i++, sb++) {
tb = t; /* Reset the pointer to the beginning of the string. */
ss = sb; /* Reset the substring pointer to the base string
* pointer. */
for (j = 0; *tb != '\0' && *ss == *tb; ss++, tb++, j++) {
if (*(tb+1) == '\0' && j > 0) {
return i;
}
}
}
return -1;
}
int getop (char *str)
{
int c;
while ((*str++ = c = getch()) == ' ' || c == '\t');
*str = '\0';
if (!isdigit(c) && c != '.') {
return c;
}
if (isdigit(c)) {
while (isdigit(*str++ = c = getch()));
}
if (c == '.') { /* Collect fraction. */
while (isdigit(*str++ = c = getch()));
}
*--str = '\0'; /* Compensate for the extra character. */
if (c != EOF) {
ungetch(c); /* Return extra charater to the stack. */
}
return NUMBER;
}
char buf[BUFSIZE]; /* The Stack */
int bufp = 0; /* Top Position on the stack */
int getch (void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch (int c)
{
if (bufp >= BUFSIZE) {
printf("ungetch: too many characters.\n");
} else {
buf[bufp++] = c;
}
}
menonsahab's:
/**************************** atoi() ********************************/
#include <stdio.h>
#include <ctype.h>
#define SIZE 100
int main()
{
char str[SIZE];
scanf("%s", str);
printf("string = %s, number = %d\n", str, atoi(str));
return 0;
}
int atoi(char *s)
{
int sign, n = 0;
while(isspace(*s))
s++;
sign = (*s == '-') ? -1 : 1;
if(*s == '+' || *s == '-')
s++;
while(isdigit(*s))
{
n = 10 * n + (*s-'0');
s++;
}
return sign*n;
}
/********************************************************************/
/*************************** itoa() *********************************/
#include <stdio.h>
#define SIZE 100
char *itoa(int n, char *s);
void reverse(char *s);
int main()
{
int num;
char str[SIZE];
scanf("%d", &num);
printf("num = %d, string = %s\n", num, itoa(num, str));
return 0;
}
char *itoa(int n, char *s)
{
int sign;
char *p = s;
sign = (n < 0) ? -1 : 1;
(sign < 0) ? n = -n : 0; // Won't work for n = INT_MIN, store -n in an unsigned variable if required
while(n > 0)
{
*p++ = n%10 + '0';
n = n / 10;
}
(sign == -1) ? (*p++ = '-') : 0;
*p = '\0';
reverse(s);
return s;
}
void reverse(char *s)
{
char *p;
int temp;
p = s;
while(*p)
p++;
p--;
while(s<=p)
{
temp = *s;
*s = *p;
*p = temp;
s++;
p--;
}
}
/********************************************************************/
/**************************** reverse() *****************************/
#include <stdio.h>
#define SIZE 100
void reverse(char *s);
int main()
{
char str[SIZE];
scanf("%s", str);
printf("string = %s\n", str);
reverse(str);
printf("reversed string = %s\n", str);
return 0;
}
void reverse(char *s)
{
char *p;
int temp;
p = s;
while(*p)
p++;
p--;
while(s<=p)
{
temp = *s;
*s = *p;
*p = temp;
s++;
p--;
}
}
/********************************************************************/
/****************************** strindex() **************************/
#include <stdio.h>
#define SIZE 100
int main()
{
char s[SIZE], t[SIZE];
scanf("%s", s);
scanf("%s", t);
printf("strindex(%s, %s) = %d\n", s, t, strindex(s, t));
return 0;
}
int strindex(char *s, char *t)
{
int tlen, count;
char *p, *q, *r;
q = t;
while(*q++);
q--;
tlen = q-t;
for(p = s; *p ; p++)
{
count = 0;
r = p;
for(q = t; *q ; q++, r++)
{
if(*r == *q)
count++;
else
break;
}
if(count == tlen)
return (int)(p-s);
}
return -1;
}
/********************************************************************/
/**************************** getop() *******************************/
#include <stdio.h>
#include <ctype.h>
#define SIZE 100
#define NUMBER '0'
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp>0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
int main()
{
char str[SIZE];
int type;
while((type = getop(str)) != EOF)
printf("type = %d, str = %s\n", type, str);
return 0;
}
int getop(char *s)
{
int c;
while(isspace(*s = c = getch()));
*(s+1) = '\0';
if(!isdigit(c) && c != '.')
return c;
if(isdigit(c))
while(isdigit(*++s = c = getch()));
if(c == '.')
while(isdigit(*++s = c = getch()));
*++s = '\0';
if(c != EOF)
ungetch(c);
return NUMBER;
}
/********************************************************************/
'The C Programming Language' 카테고리의 다른 글
Chapter 5 - Pointers and Arrays 8 (0) | 2009.03.27 |
---|---|
Chapter 5 - Pointers and Arrays 7 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 5 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 4 (0) | 2009.03.27 |
Chapter 5 - Pointers and Arrays 3 (0) | 2009.03.27 |