Right now I'm working my way through "The C Programming Language" book and boy has it been a humbling experience. Right now I'm working on exercise 2-3 in the book and I can't figure out where I've gone wrong with my squeeze() function. The purpose of the function is to delete any characters in string 1 that are found in string 2. Right now all my function does is delete the first char of string1 if it's found in string2 and then acts strangely after that.. I looked in the answer book and the answer given is very confusing to me. It's hard to make sense of what is being done, so instead of following the logic in the answer book I sort of want to know where I'm going wrong in my own code... Here's the code below:
/* Write an alternate version of squeeze(s1, s2) that deletes each char in s1 that matches
* any char in string s2 */
/* Here's a reference for squeeze(s1, s2):
* squeeze: delete all c from s
*
* void squeeze(char s[], int c)
* {
* int i, j;
*
* for(i = j = 0; s[i] != '\0'; i++)
* if(s[i] != c)
* s[j++] = s[i];
* s[j] = '\0';
* }
*******************************************/
#include <stdio.h>
#include <string.h>
#define MAX_INPUT 100
void squeeze(char string1[], char string2[]);
int main()
{
int c, i = 0, j = 0;
char s1[MAX_INPUT + 2], s2[MAX_INPUT + 2];
printf("\nPlease enter string1\n");
while((c = getchar()) != '\n')
{
s1[i] = c;
i++;
}
s1[i] = '\0';
/* test to see if above worked */
printf("\ns1 = %s\n", s1);
printf("\nPlease enter string2\n");
while((c = getchar()) != '\n')
{
s2[j] = c;
j++;
}
s2[j] = '\0';
/* test to see if above worked */
printf("\ns2 = %s\n", s2);
printf("\nWe will now apply the squeeze function to remove any chars");
printf(" found in string2 from string1\n");
squeeze(s1, s2);
printf("Squeeze(s1, s2) = %s\n", s1);
}
void squeeze(char s1[], char s2[])
{
int i = 0, j = 1; /* for counters */
char temp; /* for char comparison */
temp = s2[0];
while(s2[i] != '\0')
{
if(s1[i] == temp)
{
s1[i] = s1[i+1];
j++;
}
else
{
j++;
}
temp = s2[j];
i++;
}
s1[i+1] = '\0';
}
My output is the following:
Please enter string1
hello
s1 = hello
Please enter string2
help
s2 = help
We will now apply the squeeze function to remove any chars found in string2 from string1
Squeeze(s1, s2) = eello
Can anyone spot what's wrong with my logic? From the answer book I'm guessing I need a third counter, k, somewhere but I can't see a reason for it with the way I programmed the function.. I know I'm missing something though! Thanks so much everyone :)
Answer ( thank you Vlad!) :
void squeeze(char s1[], char s2[])
{
int i = 0, j = 0;
do
{
int k = 0;
while(s2[k] != '\0' && s2[k] != s1[i])
++k;
if (s2[k] == '\0')
{
if ( j != i)
s1[j] = s1[i];
++j;
}
} while (s1[i++] != '\0');
}
Your function does not make a sense.
The while loop is executed according to the length of s2
while(s2[i] != '\0')
However you are using the same index i
for checking the string s1
.
if(s1[i] == temp)
But the string s1
can be in general shorter or larger than the string s2
. So the function can invoke undefined behavior.
Also each character in s1
shall be checked in the string s2
starting from its beginning.
The function can be declared and defined (without using standard C string functions) as it is shown in the demonstrative program below.
#include <stdio.h>
char * squeeze( char s1[], const char s2[] )
{
if ( *s2 != '\0' )
{
size_t i = 0;
size_t j = 0;
do
{
size_t k = 0;
while ( s2[k] != '\0' && s2[k] != s1[i] ) ++k;
if ( s2[k] == '\0' )
{
if ( j != i ) s1[j] = s1[i];
++j;
}
} while ( s1[i++] != '\0' );
}
return s1;
}
int main(void)
{
char s1[] = "Hello World!";
const char *s2 = "aeiou";
puts( s1 );
puts( squeeze( s1, s2 ) );
return 0;
}
The program output is
Hello World!
Hll Wrld!