K&R2 , section 5.4

A

arnuld

PURPOSE: see comments.
OUTPUT: negative integer as output even for equal strings


/* A string comparison function from K&R2
* example code from section 5.4,page 106
*
* returns +ve number , if 1st string is greater than 2nd
* return -ve number, if 2nd string is greater than 1st
* returns 0, if both are equal
*
*/

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

enum MAXSIZE { ARR_SIZE = 1000 };


int my_strcmp( char*, char* );

int main( )
{
char s1[ARR_SIZE], s2[ARR_SIZE];

strcpy( s1, "s" );
strcpy( s2, "s" );

printf( "%s\t%s\t --> %d\n", s1, s2, my_strcmp( s1, s2 ));


return EXIT_SUCCESS;
}



int my_strcmp( char* s1, char* s2 )
{
for( ; *s1 == *s2; s1++, s2++ )
{
if( s1 == '\0' )
{
return 0;
}
}

return *s1 - *s2;
}

/*

if( *s1 > *s2 )
{
return 1;
}
else if( *s1 < *s2 )
{
return -1;
}
else
{
return 0;
}
*/


==================== OUTPUT ======================
Welcome to the Emacs shell

/home/arnuld/programs/C $ gcc -ansi -pedantic -Wall -Wextra section_5-5.c
/home/arnuld/programs/C $ ./a.out
s s --> -151
/home/arnuld/programs/C $ ./a.out
s s --> -66
/home/arnuld/programs/C $ ./a.out
s s --> -122
/home/arnuld/programs/C $ ./a.out
s s --> -193
/home/arnuld/programs/C $




-- http://lispmachine.wordpress.com/

Please remove capital 'V's when you reply to me via e-mail.
 
I

Irrwahn Grausewitz

arnuld said:
PURPOSE: see comments.
OUTPUT: negative integer as output even for equal strings


/* A string comparison function from K&R2
* example code from section 5.4,page 106
*
* returns +ve number , if 1st string is greater than 2nd
* return -ve number, if 2nd string is greater than 1st
* returns 0, if both are equal
*
*/
[SNIP]

int my_strcmp( char* s1, char* s2 )
{
for( ; *s1 == *s2; s1++, s2++ )
{
if( s1 == '\0' )

Oops. I think you want:

if ( *s1 == '\0' )
 
P

Philip Potter

arnuld said:
PURPOSE: see comments.
OUTPUT: negative integer as output even for equal strings

/* A string comparison function from K&R2
* example code from section 5.4,page 106
*
* returns +ve number , if 1st string is greater than 2nd
* return -ve number, if 2nd string is greater than 1st
* returns 0, if both are equal
*/

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

enum MAXSIZE { ARR_SIZE = 1000 };


int my_strcmp( char*, char* );

int main( )

int main(void) or int main(int argc, char *argv[]) are better style. I
believe I've seen you around comp.lang.c++ where int main() is perfectly
acceptable - but in C it isn't.
{
char s1[ARR_SIZE], s2[ARR_SIZE];

strcpy( s1, "s" );
strcpy( s2, "s" );

printf( "%s\t%s\t --> %d\n", s1, s2, my_strcmp( s1, s2 ));


return EXIT_SUCCESS;
}



int my_strcmp( char* s1, char* s2 )
{
for( ; *s1 == *s2; s1++, s2++ )
{
if( s1 == '\0' )
{
return 0;
}

This test doesn't do what you think it does, and is the problem. s1 is a
'char *' value. '\0' is a character literal, which has type int and
value 0. So it's equivalent to

if (s1 == 0)

or even

if (s1 == NULL)

Since you pass non-null pointers into my_strcmp(), this test won't ever
fail. The for loop first compares 's' characters of the two arrays,
which are equal, and s1 is non-null so the loop continues. It then
compares '\0' values, which are equal, and s1 is non-null so the loop
continues. It them compares the garbage values beyond the '\0'
terminator. What happens then is undefined behaviour.

The fix is to change the line above to
if (*s1 == '\0')

}

return *s1 - *s2;
}

/*

if( *s1 > *s2 )
{
return 1;
}
else if( *s1 < *s2 )
{
return -1;
}
else
{
return 0;
}
*/

For good measure:

pgp@bullfinch:~/tmp$ cat arnuld.c
/* A string comparison function from K&R2
* example code from section 5.4,page 106
*
* returns +ve number , if 1st string is greater than 2nd
* return -ve number, if 2nd string is greater than 1st
* returns 0, if both are equal
*
*/

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

enum MAXSIZE { ARR_SIZE = 1000 };

int my_strcmp( char*, char* );

int main(void)
{
char s1[ARR_SIZE], s2[ARR_SIZE];
strcpy( s1, "s" );
strcpy( s2, "s" );
printf( "%s\t%s\t --> %d\n", s1, s2, my_strcmp( s1, s2 ));
return EXIT_SUCCESS;
}

int my_strcmp( char* s1, char* s2 )
{
for( ; *s1 == *s2; s1++, s2++ )
{
if( *s1 == '\0' )
{
return 0;
}
}
return *s1 - *s2;
}

pgp@bullfinch:~/tmp$ gcc -ansi -pedantic -W -Wall arnuld.c -oarnuld
pgp@bullfinch:~/tmp$ ./arnuld
s s --> 0
pgp@bullfinch:~/tmp$ ./arnuld
s s --> 0
pgp@bullfinch:~/tmp$ ./arnuld
s s --> 0
pgp@bullfinch:~/tmp$ ./arnuld
s s --> 0
pgp@bullfinch:~/tmp$
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top