0

I have been trying to solve this problem for about 5 days..can't find any solution please send help. I am supposed to implement a function to "delete" every element in an array by value. Let's say my array is "Hello" and I want to delete every "l". So far I can only delete l once. By the way keep in mind I am not allowed to use pointers for this function...(we haven't learned that yet in my school) Here's my code:

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

void strdel(char array[], char c);

int main(void)
{
    char source[40];
    printf("\nStrdel test: ");
    strcpy(source, "Hello");
    printf("\nsource = %s", source);
    strdel(source, 'l');
    printf("\nStrdel: new source = %s", source);
    return 0;
}

void strdel(char array[], char c)
{
    int string_lenght;
    int i;
    for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {} 

    for (i = 0; i < string_lenght; i++) {
        if (array[i] == c) {
            for (i = i; array[i] != '\0'; ++i)
                array[i] = array[i + 1];
        }
    }
}
5
  • Why don't you use strlen() to calculate length? Commented Nov 26, 2018 at 19:06
  • 3
    Tip - use a 'read' index and a 'write' index. Start them the same and increment each as necessary... Commented Nov 26, 2018 at 19:06
  • 1
    don't use the same variable i in different for loops Commented Nov 26, 2018 at 19:06
  • i'm not allowed to use other functions to implement strdel that's why i don't use strlen... I can only write them in main to test if my function is correct Commented Nov 26, 2018 at 19:10
  • i = i; was your clue that things weren't right Commented Nov 26, 2018 at 19:29

2 Answers 2

5

Simple use 2 indexes, one for reading and one for writing. @Carl Norum

void strdel(char array[], char c) {
  int read_index = 0;
  int write_index = 0;
  while (array[read_index] != '\0') {
    if (array[read_index] != c) {
      array[write_index] = array[read_index];
      write_index++;  // Only advance write_index when a character is copied
    }
    read_index++;     // Always advance read_index
  }
  array[write_index] = '\0';
}

The has O(n) performance, much faster than using nested for() loops which is O(n*n).


Details:

OP: By the way keep in mind I am not allowed to use pointers for this function.

Note that array in void strdel(char array[], char c) is a pointer, even though it might look like an array.

int for array indexing is OK for learner and much code, yet better to use size_t. int may lack the range needed. Type size_t is an unsigned type that is neither too narrow nor too wide for array indexing needs. This becomes important for very long strings.

Sign up to request clarification or add additional context in comments.

6 Comments

The while(array[read_index]) may be confusing for a new programmer - I'd suggest explaining that when it's null, that statement will fail (or even using a for loop in the example and explaining how it can be compressed to a while - that way the comparison is still visible)
@BrydonGibson Amended while (array[read_index]) to while (array[read_index] != '\0') which is functionally equivalent.
No idea what while(array[read_index]) does. How does that work ? the rest is somewhat clear
@Saty while (test_condition) tests if test_condition != 0.
I've tested your code and for my array: "Hello" and "l" I only get ll instead of Heo ? Why is that ? I'm still trying to understand why you use only 1 while loop
|
3

Your problem is related to using the variable i in both loops. So once the inner loop is executed, outer loop will terminate right after.

Use another variable for the inner loop.

void strdel(char array[], char c)
{
    int string_lenght;
    int i, j;
    for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {} 

    for (i = 0; i < string_lenght; i++) {
        if (array[i] == c) {
            for (j = i; array[j] != '\0'; ++j)  // Use variable j instead of i
                array[j] = array[j + 1];

           --i;              // Decrement i to "stay" at the same index
           --string_lenght;  // As one character were just removed
        }
    }
}

The above shows how to make OPs approach work. For a better solution see the answer from @chux : https://stackoverflow.com/a/53487767/4386427

2 Comments

Thanks so much ! I used read_index and write_index for i and j so that it's a bit clearer.... Could you please explain why you need to use --i after the second for loop ? That was the key step that i was always missing...
@Saty The --i is needed to stay at the same index in the next loop. In other words - it cancels the ++i in the for statement

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.