Charles Day
Charles Day

Reputation: 41

How do I remove all occurrences of a letter in c, only using pointer and pointer arithmetic.

I need help editing this code to remove any occurrence of a specific letter(defined by the user) in a single character array. Here is my code thus far.

void removeLetter(char string[STRING_LENGTH], char letterToBeRemoved)
{
    char *p1 = string;
    size_t length = strlen(string);
    for (int i = 0; i < length-1; i++)
{
    if (*p1 = letterToBeRemoved)
    {
        for (int j = 0; j < length; j++)
        {
            *p1 = *(p1 + 1);
        }
    }
    ++p1;
 }
}

I do not know what the problem is? Is this not similar to java, in the sense that you find the letter then move all the ones after down one. I am new to c and it is very difficult for me. Thanks

Upvotes: 0

Views: 513

Answers (4)

Raj Samant
Raj Samant

Reputation: 41

#include <stdio.h>

#define STRING_LENGTH 100

void removeLetter(char mystring[STRING_LENGTH], char letterToBeRemoved) {
    char *p1, *p2;
    p1 = p2 = mystring;

    while(*p1 != '\0') {
        if(*p1 != letterToBeRemoved)
            *p2++ = *p1;
        p1++;
    }
    *p2 = *p1;
}

int main() {
    char s[100] = "hi how are you henna.";
    char *p = s;

    while(*p != '\0')
        printf("%c", *p++);
    printf("\n");

    removeLetter(s, 'h');

    p = s;
    while(*p != '\0')
         printf("%c", *p++);
    printf("\n");

    return 0;
}

I have used two pointers, where one pointer is simple pointer 'p1' and iterates all letters in string. Second pointer 'p2' only copies letter which are not equal to 'letterToBeRemoved'. Note: 'p2' pointer always will be same speed or slower speed than 'p1'.

Upvotes: 0

chux
chux

Reputation: 154166

Instead, walk through the array and update the destination when the source is not the special char.

void removeLetter(char *string, char letterToBeRemoved) {
  // attempting to remove the null character is pathological.
  assert(letterToBeRemoved);
  char *dest = string;
  do {
    while (*string == letterToBeRemoved) string++;
    *dest = *string++;
  } while (*dest++);
}

Upvotes: 0

Ben
Ben

Reputation: 2937

Faster solution makes one pass copy what you need backwords in the array, essentially overwriting the letters you want to remove.

#include <iostream>
using namespace std;

const size_t STRING_LENGTH = 12;

void removeLetter(char* string, char letterToBeRemoved)
{
    // pBack will look at each letter in the array 
    // and copy only valid letters to pFront
    // pFront is incremented only when valid letters are copied to it.
    char* pBack = string;
    char* pFront = string;
    while ((pBack - string) < STRING_LENGTH)
    {
        if (*pBack != letterToBeRemoved)
        {
            *pFront = *pBack;
            pFront++;
        }
        pBack++;
    }

    // Terminate string if we removed something
    if ((pBack - string) != (STRING_LENGTH - 1))
    {
        *pFront = '\0';
    }


}

int main() {
    char input[STRING_LENGTH] = "hello world";
    removeLetter(input, 'l');
    std::cout << input << std::endl;
    return 0;
}

See it here: http://ideone.com/t3Obxw

Upvotes: 1

paddy
paddy

Reputation: 63481

You want equality, not assignment:

if (*p1 == letterToBeRemoved)
//       ^

You don't need an O(n^2) algorithm (like you have implemented using an inner loop) to do this. Instead, walk through the array, and every time you find a letter to remove, increment the step amount for how far ahead you are copying characters.

Upvotes: 0

Related Questions