Please review my tutorial

From: Sathyaish (VisualBasicLearner_at_yahoo.com)
Date: 11/01/04


Date: 1 Nov 2004 04:00:36 -0800

I had recieved an email sometime ago wherein I was asked to write a
function that parsed a given string for the longest pallindrome it
contained and replaced the pallindrome with another string, given as
its second argument. In finding a pallindrome, however, all the
characters were to be considered equal. Therefore, a space, a comma,
or any punctuation for that matter was to be treated like any other
character.

In solving that question, here's what I came up with after a try or
two:

//File R.h
#ifndef __R__
#define __R__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_LEN 1000

int ReplacePallindromes(char**, char*);
int Replace(char**, const int, const int, const
char*);
char* SubString(char*, const int, const int);
void Reverse(char*);

enum MatchTypes
{
None=0,
OddLength=1,
EvenLength=2
};

#endif

//File Globals.h
#include "R.h"

int ReplacePallindromes(char **InStr, char
*ReplaceWith)
{

int Len, LenReplaceWith, MatchFound, LastReplacement;

int Counter;
int ReverseCounter;
int SomeCounter;
int SomeOtherCounter;

char* SubStr1;
char* SubStr2;

LastReplacement=-100;
SubStr1=SubStr2=NULL;
MatchFound=0;

if (*InStr==NULL || ReplaceWith==NULL) return -1;
if (*ReplaceWith==0) return -1;
LenReplaceWith=strlen(ReplaceWith);
Len=strlen(*InStr);
if (Len<2) return -1;

Counter=ReverseCounter=SomeCounter=SomeOtherCounter=0;

for(Counter=0; Counter<Len; Counter++)
{

NextCharFromFront:
    for(ReverseCounter=Len-1; ReverseCounter>Counter;
ReverseCounter--)
    {
        if (*((*InStr)+Counter) == *((*InStr)+ReverseCounter))
        {
            MatchFound=1;
            for(SomeCounter=1, SomeOtherCounter=ReverseCounter-1;
            Counter+SomeCounter<=SomeOtherCounter; SomeCounter++,
SomeOtherCounter--)
            {
                SubStr1=SubString(*InStr, Counter,
Counter+SomeCounter);

                SubStr2=SubString(*InStr, SomeOtherCounter,
ReverseCounter);
                Reverse(SubStr2);

                MatchFound=((strcmp(SubStr1, SubStr2)==0)? 1:0);
                if (MatchFound==0)
                {
                    free(SubStr1);
                    free(SubStr2);
                    break;
                }
                
                free(SubStr1);
                free(SubStr2);
            }//End of SomeCounter for loop

            if(MatchFound==1 && Counter+SomeCounter>=SomeOtherCounter)
            {
                //This is the largest pallindrome, replace it
                LastReplacement=Replace(InStr, Counter,
ReverseCounter, ReplaceWith);
                Len=strlen(*InStr);
                Counter=LastReplacement+1;
                goto NextCharFromFront;
            }
        }//End of if InStr[Counter] == InStr[ReverseCounter]
    }//End of ReverseCounter for loop
}// End of Counter for loop

return 0;

} //end of function

int Replace(char **InStr, const int From,
const int To, const char *ReplaceWith)
{

char* NewString;
int LenReplaceWith, Counter, k, Len;

if(*InStr==NULL || ReplaceWith==NULL) return -1;
Len=strlen(*InStr);
LenReplaceWith=strlen(ReplaceWith);

NewString=NULL;

NewString=(char*)malloc(sizeof(char)*(Len-(To-From+1)+LenReplaceWith+1));
for(Counter=0;
Counter<(Len-(To-From+1)+LenReplaceWith+1); Counter++)
*(NewString+Counter)=0;

for(Counter=0;Counter<=From-1;Counter++)
*(NewString+Counter)=*((*InStr)+Counter);

for(Counter=0;Counter<LenReplaceWith; Counter++)
 *(NewString+From+Counter)=*(ReplaceWith+Counter);

for(Counter=To+1, k=0; Counter<Len; Counter++, k++)
    *(NewString+From+LenReplaceWith+k)=*((*InStr)+Counter);

*(NewString+From+LenReplaceWith+k)=0;

free(*InStr);
Len=strlen(NewString);
*InStr=(char*)malloc(sizeof(char)*(Len+1));
if((*InStr)==NULL) return -1;
strcpy(*InStr, NewString);
free(NewString);

return (From-1+LenReplaceWith);

}

char* SubString(char* Source, const int From, const
To)
{

int Len, Counter;
char *NewString;
Len=strlen(Source);
if(Source==NULL) return NULL;
if (From<0) return NULL;
if (From>To) return NULL;
if ((From>Len) || (To>Len)) return NULL;
NewString=(char*)malloc(sizeof(char)*(To-From+2));
for(Counter=From; Counter<=To; Counter++)
{
*(NewString+Counter-From)=*(Source+Counter);
}
NewString[Counter-From]=0;
return NewString;
}

void Reverse(char* Str)
{
int i, j, len;
char temp;
i=j=len=temp=0;

if(Str!=NULL)
{
len=strlen(Str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=Str[i];
Str[i]=Str[j];
Str[j]=temp;
}
}
}

//File R.C
#include "R.h"

int main(void)
{

char c, *InStr, *ReplaceWith;
int i;

c=' ';
i=0;

InStr=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(InStr==NULL) return -1;
ReplaceWith=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(ReplaceWith==NULL) return -1;

printf("\nEnter a string (1000 characters maximum):");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN)) InStr[i++]=c;
InStr[i]=0;

c=' ';
i=0;
printf("\n\nEnter the string that you wish to replace\npallindromes
with (1000 characters maximum): ");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN))
ReplaceWith[i++]=c;
ReplaceWith[i]=0;

    if(ReplacePallindromes(&InStr, ReplaceWith)==0)
    {
        printf("\nThe modified string is:\n\n %s\n", InStr);
    }
    else
    {
        printf("An error occured. The program will now end.");
        free(InStr);
        free(ReplaceWith);
        return -1;
    }

    free(InStr);
    free(ReplaceWith);
    return 0;
}

I was asked as to why I'd taken a pointer to a pointer as the first
argument of the ReplacePallindrome function. I thought I'd write a
tutorial to explain this thing that I'd arrived at by heuristic
endeavours in the past, when I practiced pointers. So here's a
tutorial I've written. Even at the risk of being laughed at, I present
it to all of you learned people out here, so you may review it,
because, with a few refinements, I intend to get it published if it is
all ok. I am only learning C and thus have written only what I've
coded and tested with my own hands. Please give me your comments as to
how good or bad it is.

http://sathyaishc.tripod.com/Tutorial.doc

(You have to do a right-click and say "Save As" or "Save Target As")

Thanks!