Exercise 5-6. 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).
#include <stdio.h> // for printf()
#include <string.h> // for strlen()
#define SIZE 100 // array size
void escape(char *s, char *t); // copy t to s making escapes visible
int trim(char *s, int len); // remove beginning and trailing whitespace
int main()
{
char empty[] = " \t\r\n \t\v\f\n";
int len = strlen(empty);
char array[SIZE*2];
escape(array, empty); // empty does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(empty, len); // empty is trimmed
printf("\"%s\"[%d]\n", empty, len);
char nonempty[] = "\t \f \v\r\nHello \n\v\r\f \t";
len = strlen(nonempty);
escape(array, nonempty); // nonempty does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(nonempty, len); // nonempty is trimmed
printf("\"%s\"[%d]\n", nonempty, len);
char nowhite[] = "Hello";
len = strlen(nowhite);
escape(array, nowhite); // nowhite does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(nowhite, len); // nowhite is trimmed
printf("\"%s\"[%d]\n", nowhite, len);
return 0;
}
void escape(char *s, char *t) // copy t to s making escapes visible
{
for ( ; *t != '\0'; t++)
{
switch(*t)
{
case '\'' :
*s++ = '\\'; *s++ = '\'';
break;
case '\"' :
*s++ = '\\'; *s++ = '\"';
break;
case '\t' :
*s++ = '\\'; *s++ = 't';
break;
case '\n' :
*s++ = '\\'; *s++ = 'n';
break;
case '\r' :
*s++ = '\\'; *s++ = 'r';
break;
case '\f' :
*s++ = '\\'; *s++ = 'f';
break;
case '\v' :
*s++ = '\\'; *s++ = 'v';
break;
case '\a' :
*s++ = '\\'; *s++ = 'a';
break;
case '\b' :
*s++ = '\\'; *s++ = 'b';
break;
case '\\' :
*s++ = '\\'; *s++ = '\\';
break;
default:
*s++ = *t; // copy non-escapes
break;
}
}
*s = '\0'; // properly end string
}
// remove beginning and trailing whitespace
int trim(char *s, int len)
{
char *p; // new length
for (p = s+len-1; p >= s; p--)
{
if (*p != ' ' && *p != '\t' && *p != '\n' &&
*p != '\f' && *p != '\v' && *p != '\r')
{break;} // out of for()
// else {continue;}
}
p++;
*p = '\0';
if (p == s) {return 0;} // (p-s) == 0 // empty string
len = p-s; // new length after trimming trailing whitespace
// here s[len-1] is not whitespace, but s may have beginning whitespace
for (p = s; (p-s) < len; p++)
{
if (*p == ' ' || *p == '\t' || *p == '\n' ||
*p == '\f' || *p == '\v' || *p == '\r')
{continue;}
else {break;} // out of for()
} // (p-s) counts no of beginning whitespaces
len -= (p-s); // len = len-(p-s); // final length
if (p == s) {return len;} // no beginning whitespace
char *t;
for (t = s ; len > 0; t++, p++, len--) // while (len)
{ // shift string to the beginning, thus removing
*t = *p; // the beginning whitespace
}
*t = '\0'; // s[t-s] = '\0';
return (t-s); // old len
}
/*
gcc trim.c -o trim
./trim
trim(" \t\r\n \t\v\f\n"[10]): ""[0]
trim("\t \f \v\r\nHello \n\v\r\f \t"[19]): "Hello"[5]
trim("Hello"[5]): "Hello"[5]
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf()
#include <string.h> // for strlen()
#define SIZE 100 // array size
void escape(char *s, char *t); // copy t to s making escapes visible
int trim(char *s, int len); // remove beginning and trailing whitespace
// trim with gotos
int main()
{
char empty[] = " \t\r\n \t\v\f\n";
int len = strlen(empty);
char array[SIZE*2];
escape(array, empty); // empty does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(empty, len); // empty is trimmed
printf("\"%s\"[%d]\n", empty, len);
char nonempty[] = "\t \f \v\r\nHello \n\v\r\f \t";
len = strlen(nonempty);
escape(array, nonempty); // nonempty does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(nonempty, len); // nonempty is trimmed
printf("\"%s\"[%d]\n", nonempty, len);
char nowhite[] = "Hello";
len = strlen(nowhite);
escape(array, nowhite); // nowhite does not change
printf("trim(\"%s\"[%d]): ", array, len);
len = trim(nowhite, len); // nowhite is trimmed
printf("\"%s\"[%d]\n", nowhite, len);
return 0;
}
void escape(char *s, char *t) // copy t to s making escapes visible
{
for ( ; *t != '\0'; t++)
{
switch(*t)
{
case '\'' :
*s++ = '\\'; *s++ = '\'';
break;
case '\"' :
*s++ = '\\'; *s++ = '\"';
break;
case '\t' :
*s++ = '\\'; *s++ = 't';
break;
case '\n' :
*s++ = '\\'; *s++ = 'n';
break;
case '\r' :
*s++ = '\\'; *s++ = 'r';
break;
case '\f' :
*s++ = '\\'; *s++ = 'f';
break;
case '\v' :
*s++ = '\\'; *s++ = 'v';
break;
case '\a' :
*s++ = '\\'; *s++ = 'a';
break;
case '\b' :
*s++ = '\\'; *s++ = 'b';
break;
case '\\' :
*s++ = '\\'; *s++ = '\\';
break;
default:
*s++ = *t; // copy non-escapes
break;
}
}
*s = '\0'; // properly end string
}
// remove beginning and trailing whitespace
int trim(char *s, int len)
{
char *p;
for (p = s+len-1; p >= s; p--)
{
switch (*p)
{
case ' ' : case '\t' : case '\n' :
case '\f' : case '\v' : case '\r' :
break; // continue; // go to next for() iteration
default:
goto out1; // break would just exit switch() and continue
} // with the next for() iteration
}
out1: // first label for goto
p++; // new length after trimming trailing whitespace
*p = 0;
if (p == s) {return 0;} // (p-s) == 0 // empty string
len = p-s; // new length after trimming trailing whitespace
// here s[len-1] is not whitespace, but s may have beginning whitespace
for (p = s; (p-s) < len; p++)
{
switch (*p)
{
case ' ' : case '\t' : case '\n' :
case '\f' : case '\v' : case '\r' :
break; // continue; // go to next for() iteration
default:
goto out2; // break would just exit switch() and continue
} // with the next for() iteration
}
out2: // second label for goto
// p-s counts no of beginning whitespaces
len -= (p-s); // len = len-(p-s); // final length
if (p == s) {return len;} // no beginning whitespace
char *t;
for (t = s ; len > 0; t++, p++, len--) // while (len)
{ // shift string to the beginning, thus removing
*t = *p; // the beginning whitespace
}
*t = '\0'; // s[t-s] = '\0';
return (t-s); // old len
}
/*
gcc trimg.c -o trimg
./trimg
trim(" \t\r\n \t\v\f\n"[10]): ""[0]
trim("\t \f \v\r\nHello \n\v\r\f \t"[19]): "Hello"[5]
trim("Hello"[5]): "Hello"[5]
*/