                         TEXT HANDLING WITH C

                            Matthew Probert

                           Servile  Software


Human languages write information down as 'text'. This is comprised of 
words, figures and punctuation. The words being made up of upper case 
and lower case letters. Processing text with a computer is a commonly 
required task, and yet quite a difficult one. 

The ANSI C definitions include string processing functions that are by 
their nature sensitive to case. That is the letter 'A' is seen as 
distinct from the letter 'a'. This is the first problem that must be 
overcome by the programmer. Fortunately both Borland's Turbo C 
compilers and Microsoft's C compilers include case insensitive forms 
of the string functions. 

stricmp() for example is the case insensitive form of strcmp(), and 
strnicmp() is the case insensitive form of strncmp(). 

If you are concerned about writing portable code, then you must 
restrict yourself to the ANSI C functions, and write your own case 
insensitive functions using the tools provided. 

Here is a simple implementation of a case insensitive version of 
strstr(). The function simply makes a copy of the parameter strings, 
converts those copies both to upper case and then does a standard 
strstr() on the copies. The offset of the target string within the 
source string will be the same for the copy as the original, and so it 
can be returned relative to the parameter string. 

char *stristr(char *s1, char *s2)
{
    char c1[1000];
    char c2[1000];
    char *p;

    strcpy(c1,s1);
    strcpy(c2,s2);

    strupr(c1);
    strupr(c2);

    p = strstr(c1,c2);
    if (p)
        return s1 + (p - c1);
    return NULL;
}

This function scans a string, s1 looking for the word held in s2. The 
word must be a complete word, not simply a character pattern, for the 
function to return true. It makes use of the stristr() function 
described previously. 

int word_in(char *s1,char *s2)
{
    /* return non-zero if s2 occurs as a word in s1 */
    char *p;
    char *q;
    int ok;

    ok = 0;
    q = s1;

    do
    {
        /* Locate character occurence s2 in s1 */
        p = stristr(q,s2);
        if (p)
        {
            /* Found */
            ok = 1;

            if (p > s1)
            {
                /* Check previous character */
                if (*(p - 1) >= 'A' && *(p - 1) <= 'z')
                    ok = 0;
            }

            /* Move p to end of character set */
            p += strlen(s2);
            if (*p)
            {
                /* Check character following */
                if (*p >= 'A' && *p <= 'z')
                    ok = 0;
            }
        }
        q = p;
    }
    while(p && !ok);
    return ok;
}


Some more useful functions for dealing with text are truncstr() that 
truncates a string; 

void truncstr(char *p,int num)
{
    /* Truncate string by losing last num characters */

    if (num < strlen(p))
        p[strlen(p) - num] = 0;
}

trim() that removes trailing spaces from the end of a string;

void trim(char *text)
{
    /* remove trailing spaces */
    char *p;

    p = &text[strlen(text) - 1];
    while(*p == 32 && p >= text)
        *p-- = 0;
}

strlench() that changes the length of a string by adding or deleting 
characters; 

void strlench(char *p,int num)
{
    /* Change length of string by adding or deleting characters */

    if (num > 0)
        memmove(p + num,p,strlen(p) + 1);
    else
    {
        num = 0 - num;
        memmove(p,p + num,strlen(p) + 1);
    }
}

strins() that inserts a string into another string;

void strins(char *p, char *q)
{
    /* Insert string q into p */
    strlench(p,strlen(q));
    strncpy(p,q,strlen(q));
}

strchg() that replaces all occurences of one sub-string with another 
within a target string; 

void strchg(char *data, char *s1, char *s2)
{
    /* Replace all occurences of s1 with s2 */

    char *p;
    char changed;

    do
    {
        changed = 0;
        p = strstr(data,s1);
        if (p)
        {
            /* Delete original string */
            strlench(p,0 - strlen(s1));

            /* Insert replacement string */
            strins(p,s2);
            changed = 1;
        }
    }
    while(changed);
}


