String Comparision

U

user34

(Sorry if this gets posted twice)
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get
modified somehow in the comp function and as a result i am getting
incorrect results.
Can anyone please point out the error?


#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}
 
O

osmium

user34 said:
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get modified
somehow in the comp function and as a result i am getting incorrect
results.
Can anyone please point out the error?


#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);

You return after examining the first char, no matter how it turns out.
Rethink your logic.
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}
 
U

user34

osmium said:
You return after examining the first char, no matter how it turns out.
Rethink your logic.

Can you elaborate? The for loop should parse the string until the
characters in the two strings differ ,is'nt it?
 
F

Flash Gordon

user34 wrote, On 29/04/07 17:53:
(Sorry if this gets posted twice)
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get
modified somehow in the comp function and as a result i am getting
incorrect results.
Can anyone please point out the error?

First off, did you copy and paste or retype? I suspect you retyped and
in the process typed correctly what is wrong in the copy you ran.
#include<stdio.h>

They stopped charging for white space yesterday, so your could make the
above easier to read by doing
#include said:
int comp(char *s,char *t)

Since this function is not meant to modify the strings it would be
better to make it explicit
int comp(const char *s,const char *t)

This will also mean the compiler will bitch at you if you try to modify
them.
{
for(;*s==*t;s++,t++);

It is easy to fail to spot the semicolon above, for the human reader
something like
for (; *s==*t; s++,t++) continue;
Or
for (; *s==*t; s++,t++) /* do nothing */ ;
Or
for (; *s==*t; s++,t++) {}

Also, what if both strings are entirely the same? In that case you will
not stop at the end of the strings but will continue going in to the
wild blue yonder.
for (; *s && *s==*t; s++,t++) continue;
if(*s=='\0')
return 0;
else
return (*s -*t);

You do not need the parenthesis
return *s - *t;

Also, on some embedded systems where a byte (in C terms) is 16 bits or
larger and the same size as an int this could fail.
return (*s > *t) ? 1 : -1;
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}

You should add a newline on to the end of the strings. One easy way as
you are not using any format specifiers is to call puts instead of printf.
 
F

Flash Gordon

user34 wrote, On 29/04/07 18:15:
Can you elaborate? The for loop should parse the string until the
characters in the two strings differ ,is'nt it?

Also it won't stop at the end of the strings if they are the same.
 
U

user34

Flash said:
user34 wrote, On 29/04/07 17:53:

First off, did you copy and paste or retype? I suspect you retyped and
in the process typed correctly what is wrong in the copy you ran.

I did not retype the code !
Here it is once again (without any of the above suggested
improvements)and it still shows me the same error!

#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}
 
F

Flash Gordon

user34 wrote, On 29/04/07 18:29:
I did not retype the code !
Here it is once again (without any of the above suggested
improvements)and it still shows me the same error!

<snip>

Then your description of the problem is inaccurate, the code does not
modify the strings. I suggest you examine the improvements and comments
by myself and the others and see if it then works.
 
O

osmium

user34 said:
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get modified
somehow in the comp function and as a result i am getting incorrect
results.
Can anyone please point out the error?


#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}

The first problem I note is that the terminating condition on the for loop
should be an '\0', signifying end of string. This suggests the middle
expression should be something like

*s!='\0' && *t'='\0'

But this doesn't work because we don't know if both strings are the same
length. So now we precede your code with something to find the length of
the strings. But that uses stuff in <string.h>, the very thing you are
trying to avoid! But then note that you are barely using a for loop, it is
a force fit. I suggest you rewrite using a while loop. I don't like
suggesting new and different ways to attack a problem, but even more, I
don't like the code I foresee if the for loop approach is continued.

I consider the primary good attribute of a for loop the index variable. But
you don't *use* an index variable.
 
F

Flash Gordon

osmium wrote, On 29/04/07 19:03:
user34 said:
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get modified
somehow in the comp function and as a result i am getting incorrect
results.
Can anyone please point out the error?


#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}

The first problem I note is that the terminating condition on the for loop
should be an '\0', signifying end of string. This suggests the middle
expression should be something like

*s!='\0' && *t'='\0'

But this doesn't work because we don't know if both strings are the same
length. So now we precede your code with something to find the length of
the strings.

Actually, you don't have to worry about whether the strings are the same
length, of even check for the end of both strings. After all, is the
strings are of different lengths then when you get to the end of the
shorter string you will find that '\0'!=character.
> But that uses stuff in <string.h>, the very thing you are
trying to avoid! But then note that you are barely using a for loop, it is
a force fit. I suggest you rewrite using a while loop. I don't like
suggesting new and different ways to attack a problem, but even more, I
don't like the code I foresee if the for loop approach is continued.

I consider the primary good attribute of a for loop the index variable. But
you don't *use* an index variable.

The approach used by the OP is not bad, it just has an error in it.
Using an index variable is also perfectly acceptable IMHO since a decent
optimising compiler will happily convert from one to the other depending
on what is more efficient for the processor.
 
O

osmium

user34 said:
osmium wrote:

Can you elaborate? The for loop should parse the string until the
characters in the two strings differ ,is'nt it?

If you really prefer a for loop based solution, I would do it something like
this. As far as I know it works.
--------------------------
#include <stdio.h>

// return 1 iff they are equal (inverted sense from what you had)
int comp(char a[], char b[])
{
for(int i=0; ; i++)
{
if(a != b)
return 0;
/* assert: a == b, we just tested it
but it it the end of the string? */
if(a == '\0')
return 1;
}
}
/*=============*/
int main()
{
char s[] = "test";
char t[] = "test";
if(comp(s, t))
printf("Same\n");
else
printf("Different");
return 0;
}
 
M

Martin Ambuhl

osmium said:
You return after examining the first char, no matter how it turns out.
Rethink your logic.

Not true. He returns after the first instance of *s != *t.
This might not occur within the bounds of the arrays, leading to
attempting addressing errors.
This loop does one of two things
a) crashes with a memory violation or
b) always changes s and t so *s != *t.

His logic is wrong, but so is yours,

He needs to test for at least one of the pointers being 0 in the loop
for( ;*s == *t && *s ; s++, t++) /* empty loop */;
will end when *s is zero (explicit) or when *t is zero and *s isn't
(since *s != *t).

Now he can remove the useless
if(*s=='\0')
return 0;

And he should change the subtraction, if only for pedagogical reasons,
Learning to return such a difference is dangerous, since it builds a bad
habit that will bite him if
a) the objects compared are not arithmetic or
b) the subtraction might cause an overflow.
In this case, where equality is the only concern, he could simply
return *s != *t;
If he wants to maintain an order, as needed for a comparison function
for qsort, the efficiency loss, if it exists at all, is tiny from
return (*s < *t) ? -1 : (*s == *t) ? 0 : 1;
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}
 
K

Keith Thompson

user34 said:
(Sorry if this gets posted twice)
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get
modified somehow in the comp function and as a result i am getting
incorrect results.
Can anyone please point out the error?


#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}

More whitespace would be very helpful (not to the compiler, but to
your readers).

Your logic error is that, if s and t point to identical strings, you
don't stop scanning when you reach the end.

You say that the strings are modified, but the code you posted doesn't
attempt to demonstrate that. Looking at the code, it does modify the
values of s and t (as it's designed to do). But s and t are pointers,
not strings. The strings themselves are not modified.

Remember that a "string" is "a contiguous sequence of characters
terminated by and including the first null character" (C99 7.1.1p1).
It's a data layout, not a data type.

For example:

char str[] = "Hello";
char *s;
s = str;
/*
* s points to the string "Hello". (It actually points
* to the first character of the string; we refer to
* a pointer to the first character of a string as a
* pointer to the string itself).
*/

s++;
/*
* Now s points to the string "ello" (which is the trailing
* portion of the string "Hello"). The original string
* "Hello" is still there in all its salutational glory,
* and we haven't modified that string. We've merely
* modified the pointer s so it points to a different
* string, one that happens to be part of the original
* string.
*/

If you haven't already done so, take a look at the comp.lang.c FAQ,
<http://www.c-faq.com/>. Sections 4 (Pointers), 6 (Arrays and
Pointers) and 8 (Characters and Strings) should be particularly
relevant to your current issues.
 
B

Barry Schwarz

You return after examining the first char, no matter how it turns out.

I think you missed the ; at the end of the for statement.

To the original poster, this is one reason why many recommend
for ( )
;
Rethink your logic.
}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;
}


Remove del for email
 
D

Default User

user34 wrote:

I did not retype the code !
Here it is once again (without any of the above suggested
improvements)and it still shows me the same error!

#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
^
That semicolon doesn't belong.




Brian
 
O

Old Wolf

Then your description of the problem is inaccurate, the code does not
modify the strings. I suggest you examine the improvements and comments
by myself and the others and see if it then works.

He never said it did. He said that "s" and "t" were modified.
Those are pointers to char, which he increments in each
loop iteration.
 
F

Flash Gordon

Old Wolf wrote, On 29/04/07 23:40:
He never said it did. He said that "s" and "t" were modified.
Those are pointers to char, which he increments in each
loop iteration.

I can't remember exactly what he said, but my mental filters would
probably have assumed that as he was explicitly modifying those
variables he would not be surprised by them changing value. Of course, I
could be wrong.
 
D

Default User

Default said:
user34 wrote:


^
That semicolon doesn't belong.

Or maybe it did. Either way, it's not going to work.

If you leave the semicolon in, then if the strings are identical then
you read off the end of each into memory that might not belong to the
strings, or memory that had never been initialized. At any rate, it
will report a false mismatch, because it will continue that until
there's a difference.



Brian
 
A

Aditya

(Sorry if this gets posted twice)
Hi all. I am trying to learn C.As a simple exercise i tried to write a
code which would compare two strings using pointers.
However i am not getting the correct result.
On tracing the program i noticed that the strings "s" and "t" get
modified somehow in the comp function and as a result i am getting
incorrect results.
Can anyone please point out the error?

#include<stdio.h>

int comp(char *s,char *t)
{
for(;*s==*t;s++,t++);
if(*s=='\0')
return 0;
else
return (*s -*t);

}

int main(void)
{
char str[]="Hello";
char str2[]="Hello";

if(comp(str,str2)!=0)
printf("strings are different");
else
printf("strings are same");
return 0;



}- Hide quoted text -

- Show quoted text -

HI
I tried this code, it works fine!!, no idea what error u are getting..
and even the concept seems to be ok
Aditya
 
B

Barry Schwarz

He never said it did. He said that "s" and "t" were modified.
Those are pointers to char, which he increments in each
loop iteration.

Yes he did. From the original message that started this thread

"On tracing the program i noticed that the strings "s" and "t" get
modified somehow in the comp function and as a result i am getting
incorrect results."

Notice "...the strings ... get modified...." In any event, it
probably means he was misinterpreting the output from his debugger.
When pointers s and t get modified (which we all agree is the actual
modification that occurs) to point past the terminating '\0'
characters, his debugger probably attempted to show him the "string"
at the new address. Since he was in the realm of undefined behavior
at this point, what the debugger showed was equally undefined and no
longer relevant to his question.


Remove del for email
 

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
473,815
Messages
2,569,702
Members
45,492
Latest member
juliuscaesar

Latest Threads

Top