Simple string matching exercise

C

c_beginner

Dear group,

I want to implement a solution to the following link:

http://acmicpc-live-archive.uva.es/nuevoportal/data/p2006.pdf


As a beginning I am trying to implement this little sample program which
will
delete the repeated strings in two set of strings.

The code:

#include<stdio.h>
#include<stdlib.h>

enum str_match{UN_MATCHED=-1,MATCHED};

unsigned my_strmatch(const char *pattern1,char *pattern2)
{
while(pattern1 != '\0' && pattern2++ != '\0')
if( pattern1 == pattern2)
return MATCHED;
else
return UN_MATCHED;
}


int main(void)
{
char *str1 = "grammer is a important for a language isn't it";
char *str2 = "grammer is a dufficult in a language isn't it";
while(str1 != '\0' && str2 != '\0')
{
if(my_strmatch(str1,str2) == MATCHED)
free(str1);
}
printf("the remaining string are %s",str1);
return 0;
}


I know that I am making a very basic error in pointer memory allocation
which
I am not sure. Can any one help me out in doing this. Don't just write the
program
since that will be too simple for you people. Just give me a hint. Thanks.
 
R

Ruchir Bindal

you can't free string allocated with no malloc.
so char *c = "........";
free(c);

is not allowed.

hth
Ruchir
 
C

c_beginner

"c_beginner" <[email protected]>
wrote in message
Dear group,

I want to implement a solution to the following link:

http://acmicpc-live-archive.uva.es/nuevoportal/dat
a/p2006.pdf


As a beginning I am trying to implement this little sample program which
will
delete the repeated strings in two set of strings.

The code:

#include<stdio.h>
#include<stdlib.h>

enum str_match{UN_MATCHED=-1,MATCHED};

unsigned my_strmatch(const char *pattern1,char *pattern2)
{
while(pattern1 != '\0' && pattern2++ != '\0')
if( pattern1 == pattern2)
return MATCHED;
else
return UN_MATCHED;
}


int main(void)
{
char *str1 = "grammer is a important for a language isn't it";
char *str2 = "grammer is a dufficult in a language isn't it";
while(str1 != '\0' && str2 != '\0')
{
if(my_strmatch(str1,str2) == MATCHED)
free(str1);
}
printf("the remaining string are %s",str1);
return 0;
}


I know that I am making a very basic error in pointer memory allocation
which
I am not sure. Can any one help me out in doing this. Don't just write the
program
since that will be too simple for you people. Just give me a hint. Thanks.

<replay made in attachment>

you can't free string allocated with no malloc.
so char *c = "........";
free(c);

is not allowed.

hth
Ruchir

</replay made in attachment>

Ok, I just made the following change.

code:

#include<stdio.h>
#include<stdlib.h>

enum str_match{UN_MATCHED=-1,MATCHED};




unsigned my_strmatch(const char *pattern1,char
*pattern2)
{
while(pattern1 != '\0' && pattern2++ !=
'\0')
if( pattern1 == pattern2)
return MATCHED;
else
return UN_MATCHED;
}


int main(void)
{
char *str1 = malloc(sizeof *str1);
char *str2 = malloc(sizeof *str2);
if(!str1 || !str2)
{
printf("malloc error\n");
exit(1);
}
str1="grammer is a important for a language
isn't it";
str2 = "grammer is a dufficult in a language
isn't it";
while(*(str1++) != '\0' && *(str2++) != '\0')
{
if(my_strmatch(str1,str2) ==
MATCHED)
free(str1);
}
printf("the remaining string are %s",str1);
return 0;
}

end code:

I post incremented the str1 and str2 and checked
the value of the two variable.
(operator preceding rules)

If I make the following change:

while((*str1)++ != '\0' && (*str2)++ != '\0')

that is , first de-refer the pointer and apply
the post increment operator
the program shows a run time error. Can any one
explain me why?

And though the above program is correct it does
not lead to the core issue which
is deleting the matched string. Instead it frees
the whole strings. I need to work
over it.The program does not show any error but
simply does not print anything.
 
S

santosh

c_beginner wrote:
.... snip ...
Ok, I just made the following change.

#include<stdio.h>
#include<stdlib.h>

enum str_match{UN_MATCHED=-1,MATCHED};

You could have left the enumerations with their default values. As it
stands now, MATCHED will evaluate to false in a logical expression.
unsigned my_strmatch(const char *pattern1,char *pattern2)
{
while(pattern1 != '\0' && pattern2++ != '\0')
if( pattern1 == pattern2)
return MATCHED;
else
return UN_MATCHED;
}

You've got the code above totally wrong. Read a good book on basic C.
You're making several fundamental errors above.
int main(void)
{
char *str1 = malloc(sizeof *str1);
char *str2 = malloc(sizeof *str2);
if(!str1 || !str2)
{
printf("malloc error\n");
exit(1);
}
str1="grammer is a important for a language
isn't it";
str2 = "grammer is a dufficult in a language
isn't it";
while(*(str1++) != '\0' && *(str2++) != '\0')
{
if(my_strmatch(str1,str2) ==
MATCHED)
free(str1);
}
printf("the remaining string are %s",str1);
return 0;
}

end code:

I post incremented the str1 and str2 and checked
the value of the two variable.
(operator preceding rules)

If I make the following change:

while((*str1)++ != '\0' && (*str2)++ != '\0')

that is , first de-refer the pointer and apply
the post increment operator
the program shows a run time error. Can any one
explain me why?

And though the above program is correct it does
not lead to the core issue which
is deleting the matched string. Instead it frees
the whole strings. I need to work
over it.The program does not show any error but
simply does not print anything.

You've made too many fundamental mistakes in the code above to bother
explaining here. Start with a basic text on C and simple programs.
 
B

Barry Schwarz

On Sat, 25 Mar 2006 18:24:16 +0530, "c_beginner"

snip 50 lines of obsolete code

Please include only what is relevant.
</replay made in attachment>

There are no attachments in this newsgroup.
Ok, I just made the following change.

code:

#include<stdio.h>
#include<stdlib.h>

enum str_match{UN_MATCHED=-1,MATCHED};




unsigned my_strmatch(const char *pattern1,char
*pattern2)
{
while(pattern1 != '\0' && pattern2++ !=
'\0')
if( pattern1 == pattern2)
return MATCHED;
else
return UN_MATCHED;

This function returns an unsigned int. Why are you attempting to
return a negative value.
}


int main(void)
{
char *str1 = malloc(sizeof *str1);

str1 has type pointer to char. Therefore *str will always have type
char. sizeof of char is always 1. You need to know how much space
you want to allocate prior to calling malloc. If you don't know this
value when writing the code, you have to include code that will
calculate the value at the time the program executes.
char *str2 = malloc(sizeof *str2);
if(!str1 || !str2)

Good. Many forget to check for success.
{
printf("malloc error\n");
exit(1);

Use EXIT_FAILURE instead of 1 for portability.
}
str1="grammer is a important for a language
isn't it";

You went to all the trouble to have str1 point to allocated memory and
here you throw away the address of that memory, thus creating a memory
leak. The code you have replaces the current value of str1 (the
address returned by malloc) with the address of the string literal.
What you really want is to initialize the memory pointed to by str1
with contents of the string literal. This is done with code like
strcpy(str1, "grammer...");
str2 = "grammer is a dufficult in a language
isn't it";
while(*(str1++) != '\0' && *(str2++) != '\0')

Each pointer is incremented during the evaluation of the while. By
the time you get to the next if statement, your pointers no longer
point to the first character of each string. Consequently, the first
character of each will not participate in your comparison.
{
if(my_strmatch(str1,str2) ==
MATCHED)

Here you are comparing signed and unsigned values.
free(str1);
}
printf("the remaining string are %s",str1);

You just freed str1 above. You can no longer use until you
reinitialize it to point somewhere.
return 0;

You never free str2.
}

end code:

I post incremented the str1 and str2 and checked
the value of the two variable.

What the expression *str1++ actually does is
1 - evaluate to the character str1 currently points to
2 - at some point before the next sequence point, increment
the current value of str1 (so that it points to the next character)
(operator preceding rules)

If I make the following change:

while((*str1)++ != '\0' && (*str2)++ != '\0')

What the expression (*str1)++ actually does is
1 - evaluate to the character str1 currently points to
2 - some time before the next sequence point, increment the
value just evaluated (the incremented value does not participate in
the comparison and the value of the pointer itself never changes)
that is , first de-refer the pointer and apply
the post increment operator
the program shows a run time error. Can any one

What run time error?
explain me why?

And though the above program is correct it does

No it is not correct. The fact that it compiles without error is
necessary but hardly sufficient. Your code invokes undefined behavior
at multiple places.
not lead to the core issue which
is deleting the matched string. Instead it frees
the whole strings. I need to work
over it.The program does not show any error but
simply does not print anything.


Remove del for email
 
S

santosh

c_beginner said:
Dear group,

I want to implement a solution to the following link:

http://acmicpc-live-archive.uva.es/nuevoportal/data/p2006.pdf

If you follow the requirements at the link, you'll end up with a fairly
involved program. On the other hand, many of the mistakes in the code
you posted indicate you're a beginner. Why not start with simpler demos
and work your way up slowly? Acquire a good C text like K&R and start
with the sample programs and exercises.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top