Home > Enterprise >  delete leading characters before a string in C (concept question)
delete leading characters before a string in C (concept question)

Time:01-16

I’m learning C, dealing with strings and pointers. An exercise calls for deleting all leading characters (‘X’ in this case) before a string. The called function must accept a string, i.e. a pointer to a char. I have found multiple ways of doing this by searching, but I do not understand why the following code does not work...what concept am I missing?

```
    //delete all leading X characters by passing pointer to a string
    #include <stdio.h>
    #include <string.h>
    
    void delChar(char* str)
    {
        char* walker; //declare pointer
        walker = str;  //point to beginning of passed string
        
        while(*walker == 'X') walker  ; //move pointer past amy leading 'X' 
       
        printf("\nwalker string is now: %s", walker); //prints "Test" as expected
        
        str = walker; //set str pointer to walker
        printf("\nstr string is now: %s", str); //prints "Test" as expected
        
        return;
    }
    
    int main()
    {
        char* myStr = "XXXXXXXXXXXXTest";
        printf("Before function call: %s", myStr); //prints "XXXXXXXXXXXXTest" as expected
       
        delChar(myStr); //pass pointer to the string
        
        printf("\nAfter function call: %s", myStr); //WHY DOES THIS print "XXXXXXXXXXXXTest" ?
        
        return 0;
    }
``` 

CodePudding user response:

There are multiple ways in which characters can be deleted from a string, and it is not clear which you want.

In C, memory contents cannot be “deleted.” Memory is formed of bytes, and bytes hold values. When we have a string, it exists in a certain place in memory, and the bytes of the string cannot be made to go away.

Three ways to delete characters from a string are:

  • Given the start address of the string, return the address of the desired part of the string.
  • Given a pointer to the start of the string, update the pointer to point to the desired part of the string.
  • Move characters from later in the string to earlier.

Here are sample implementations:

#include <stdio.h>


/*  Deletion method 0:  Find the first character that is not an "X" and
    return its address.
*/
static char *DeleteMethod0(char *string)
{
    for (char *p = string; ;   p)
        if (*p != 'X')
            return p;
}


//  Deletion method 1:  Update the pointer to the start of the string.
static void DeleteMethod1(char **string)
{
    while (**string == 'X')
          *string;
}


//  Deletion method 2:  Move characters.
static void DeleteMethod2(char *string)
{
    //  Find the point where we stop deleting.
    char *source = string;
    while (*source == 'X')
          source;

    //  Copy the undeleted part of the string to the start.
    while (*source)
        *string   = *source  ;
    *string = '\0';
}


int main(void)
{
    char *string  = "XXXXXXXXXXXXTest";
    char buffer[] = "XXXXXXXXXXXXTest";

    printf("The string is %s.\n", string);
    printf("The buffer contains %s.\n", buffer);

    char *after = DeleteMethod0(string);
    printf("The string after deletion by getting new address %s.\n", after);

    DeleteMethod1(&string);
    printf("The string after deletion by updating the pointer is %s.\n", string);

    DeleteMethod2(buffer);
    printf("The buffer after deletion by moving characters is %s.\n", buffer);
}

Another option would be to make a new copy of the desired part of the string, in memory either supplied by the caller or allocated by the deletion routine.

CodePudding user response:

For starters the function should be declared like

char * delChar( char *str );

The function parameter str is a local variable of the function. So this assignment

str = walker;

does not change the pointer myStr declared in main. This pointer is passed to the function by value. That is the function deals with a copy of the pointer. And the assignment does not change the original pointer myStr. It changes only its local variable str that was initialized by a copy of the value of the pointer myStr.

Also you may not change a string literal. Any attempt to change a string literal results in undefined behavior. But you need indeed to change the passed string as at least followed from your assignment

delete leading characters before a string in C

That is the task is not to find the pointer that points to the first character that is not equal to 'X'. You need to remove leading characters equal to 'X' from a string.

In main you need to declare a character array instead of a pointer to a string literal as for example

char myStr[] = "XXXXXXXXXXXXTest";

The function itself can be defined the following way

char * delChar( char *str )
{
    char *walker = str;

    while ( *walker == 'X' )   walker;

    if ( walker != str ) memmove( str, walker, strlen( str )   1 - ( walker - str ) );

    return str;
}

And in main it is enough to write

printf("After function call: %s\n", delChar( myStr ) );

Here is a demonstration program

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

char * delChar( char *str )
{
    char *walker = str;

    while (*walker == 'X')   walker;

    if (walker != str) memmove( str, walker, strlen( str )   1 - ( walker - str ) );

    return str;
}

int main( void )
{
    char myStr[] = "XXXXXXXXXXXXTest";

    printf( "Before function call: %s\n", myStr );

    printf( "After function call: %s\n", delChar( myStr ) );
}

The program output is

Before function call: XXXXXXXXXXXXTest
After function call: Test

The function will be more flexible if to declare a second parameter that will specify a character that should be deleted from the beginning of a string. For example

char * delChar( char *str, char c )
{
    char *walker = str;

    while (*walker == c)   walker;

    if (walker != str) memmove( str, walker, strlen( str )   1 - ( walker - str ) );

    return str;
}

In this case the function is called like

printf( "After function call: %s\n", delChar( myStr, 'X'));

CodePudding user response:

str variable in function delChar will created over stack and store address you have passed and will be destroyed when function returns

 void delChar(char* str)   // str variable will created over stack and store address you have passed and will be destroyed when function returns
{
    char* walker; //declare pointer
    walker = str;  //point to beginning of passed string
    
    while(*walker == 'X') walker  ; //move pointer past amy leading 'X' 
   
    printf("\nwalker string is now: %s", walker); //prints "Test" as expected
    
    str = walker; //set str pointer to walker
    printf("\nstr string is now: %s", str); //prints "Test" as expected
    
    return;
}

After the return str in main will still point to start of the string.

you need to return the address and store

you can track count using counter and return the count Like below

#include<stdio.h>
int delChar(char* str)
{

int count = 0;

while(*str   == 'X') 
    count  ; // increment the count when x found 

printf("\nwalker string is now: %s", str count); 
return count;
}


int main()
{
    char* myStr = "XXXXXXXXXXXXTest";
    int count;
    printf("Before function call: %s", myStr); 
    count = delChar(myStr);
    
    printf("\nAfter function call: %s", myStr count);     
    return 0;
}
  • Related