ccharc-stringsfunction-definitionerase-remove-idiom

(Beginner) Don't know why code doesn't give correct output


Firstly, I'm trying to create a program which takes two char arrays and removes from the first any chars that shew up in the second array. I have added comments to make it easier to understand what's happening.

   #include <stdio.h>

void rcfs(char s[], char t[]){
    int i=0, j=0;
    while (t[i] != '\0')
        ++i; /*find size of t*/
    for (int x=0;x<i;++x){ /*go through both vals of x and
    check vals of s to see if they equal a val of x, if so set j of s to 0*/
        while (s[j]!=0){
            if (s[j]==t[x]){
                s[j]=0;
            }
            j++;
        }
        if (x<i-1)
            j=0;
    }
    char new[8]; /*new char arr to be assigned to s*/
    int x=0; //seperate counter that increments only when chars are added to new
    for (int q=0;q<j;q++){
        if (s[q]!=0)
            new[x++]=s[q];
    }
    new[7]=0;
    s=new; //maybe these need be pointers
}

int main(){
    char s[]="I eat food";
    char t[]="oe";
    printf("Pre: %s\n", s);
    rcfs(s, t);
    printf("Post: %s", s);
    return 0;
}

Here is the output: img Instead of 'Post: I' it should be: 'Post: I at fd' To summarise, I'm getting the wrong output and I'm currently unaware of how to fix it.


Solution

  • Your approach is entirely wrong and erroneous.

    For example this while loop

        while (s[j]!=0){
            if (s[j]==t[x]){
                s[j]=0;
            }
            j++;
        }
    

    can be unable to find a character equal to the character t[x] if already within the string s you set some preceding character to 0.

    For example if s = "12" and t = "12" then after the first iteration of the for loop

    for (int x=0;x<i;++x){
    

    the array s will look like s = "\02" So the while loop in the second iteration of the for loop will exit at once due to the condition

    while (s[j]!=0){
    

    This declaration of a character array with the magic number 8

    char new[8];
    

    does not make a sense. The user can pass to the function strings of any length.

    In this assignment statement

    s=new
    

    the local variable s of the pointer type char * (due to adjusting by the compiler the parameter having an array type to pointer to the array element type) is assigned by the address of the first element of the local array new. This does not change the source array s declared in main.

    Without using standard C string functions your function can be declared and defined the following way as it is shown in the demonstration program below.

    #include <stdio.h>
    
    char *rcfs( char s1[], const char s2[] )
    {
        if (*s2)
        {
            char *src = s1, *dsn = s1;
            do
            {
                size_t i = 0;
                while (s2[i] != '\0' && s2[i] != *src) ++i;
                if (s2[i] == '\0')
                {
                    if (src != dsn) *dsn = *src;
                    ++dsn;
                }
            } while (*src++);
        }
    
        return s1;
    }
    
    int main( void )
    {
        char s[] = "I eat food";
    
        printf( "Pre: %s\n", s );
    
        printf( "Post: %s\n", rcfs(s, "oe"));
    }
    

    The program output is

    Pre: I eat food
    Post: I at fd