5

Hi im attempting to remove a char from a C string, but the output doesnt seem correct. If for example. Input string = "Hello" Specified char to be removed = "l" My output is "HeXXo". I seem to need to push the values in after removing the char?

Code below:

#include <stdio.h>
#include <stdlib.h>

void squeeze(char str[], char c);

void main (){
  char input[100];
  char c;
  printf("Enter string \n");
  gets(input);
  printf("Enter char \n");
  scanf("%c", &c);
  printf("char is %c \n", c);
  squeeze(input , c );

  getchar();
  getchar();
  getchar();
}

void squeeze(char str[], char c){
    int count = 0, i = 0;   

    while (str[count] != '\0'){
      count++;
    }

    printf("Count = %d  \n", count);
    for ( i = 0 ; i != count; i++){
      if (str[i] == c){
            printf("Found at str[%d] \n", i);
            str[i] = "";
      }
    }
    printf(" String is = %s", str);
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
JoC
  • 243
  • 1
  • 4
  • 7
  • 2
    Some inspiration - you can implement this `squeeze` function without allocating an extra buffer. You iterate the string maintaining two pointers into it: a 'read position' pointer, and a 'write position' pointer. I don't want to spoil the fun, but this might get you started. – Frerich Raabe Oct 08 '13 at 07:56
  • Which output is a correct one? "Heo" or "Helo" or any other? – anatolyg Oct 08 '13 at 08:03
  • Freich hit the nail on the head with that hint, and you should heed it. The purpose of this exercise is to train you in walking an array sequence with two independent pointers, and the answer is simpler than you may think. And note: `gets()` is vile and evil, so much so that it is deprecated from the current standard and will not be in the next one. Don't use it. use [`fgets()`](http://en.cppreference.com/w/c/io/fgets) instead. – WhozCraig Oct 08 '13 at 08:08
  • 1
    Possible duplicate of [remove all occurences of a character in C string - Example needed](http://stackoverflow.com/questions/4161822/remove-all-occurences-of-a-character-in-c-string-example-needed) – Ciro Santilli OurBigBook.com Apr 27 '16 at 14:26

3 Answers3

5
str[i] = "";

You are trying to assign a pointer instead of a character. You probably meant ' ' but that's not the right way to delete characters from a string either, that's replacing them. Try:

char *p = str;
for (i = 0 ; i != count; i++) {
    if (str[i] != c)
        *p++ = str[i];
}
*p = 0;

EDIT

Here is a solution that I like more:

char *p = s; /* p points to the most current "accepted" char. */
while (*s) {
    /* If we accept a char we store it and we advance p. */
    if (*s != ch)
        *p++ = *s;

    /* We always advance s. */
    s++;
}
/* We 0-terminate p. */
*p = 0;
Community
  • 1
  • 1
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 1
    +1 this is the only answer that makes remote sense for the task at hand, and I'm frankly shocked at the number of answers that are repeatedly moving the same data over and over, for each space encountered, allocating space buffers, etc. Ugh. I would use two pointers, but thats minor and the overall idea is the same in this correct answer. – WhozCraig Oct 08 '13 at 08:14
  • @WhozCraig Thanks! I like the 2-pointer idiom as well (with no `i`) but I thought keeping some of the original code would be more helpful for the OP. – cnicutar Oct 08 '13 at 08:16
  • I figured that was the likely reason. – WhozCraig Oct 08 '13 at 08:17
  • You could avoid the last `*p = 0` assignment if you used a `do-while` loop. – Frerich Raabe Oct 08 '13 at 08:17
  • @FrerichRaabe or change the test condition in the for to `i <= count` either way works (assuming the string length isn't on the border of int-overflow, not a likely possibility). – WhozCraig Oct 08 '13 at 08:20
  • @WhozCraig True (and it wouldn't be an `int` overflow but a `size_t` overflow, which is considerably less likely evel). Actually, now that I think about it, there's another little bug hidden: [I think `char` may be `unsigned`](http://stackoverflow.com/questions/2054939/char-is-signed-or-unsigned-by-default) but `int` is always signed - in this case, the `str[i] != ch` comparison would fail for values > 127.... hmm, but now I see the needle is not an `int`, I must have misread - so this doesn't apply. :) – Frerich Raabe Oct 08 '13 at 08:25
  • @FrerichRaabe In the OP's code, `i` is signed, so even if `count` is not (and it is), `i` will overflow at INT_MAX+1, so I think your do-while is a better candidate regardless (or just use two pointers and be done with it =P). – WhozCraig Oct 08 '13 at 08:33
  • Yes thank you this fixed it! Could you explain it in more detail though? Im just starting out and this will really help me! – JoC Oct 08 '13 at 09:49
  • @cnicutar please let me know what s contain,i m new to programming it will more appreciated if u show all the code plz – user3632872 Jun 23 '14 at 19:45
2
#include <stdio.h>
#include <stdlib.h>

void squeeze(char str[], char c);

int main ()
{
    char input[100];
    char c;
    printf("Enter string \n");
    gets(input);
    printf("Enter char \n");
    scanf("%c", &c);
    printf("char is %c \n", c);
    squeeze(input , c );

    return 0;
}

void squeeze(char str[], char c){
    int count = 0, i = 0,j=0;
    char str2[100];
    while (str[count] != '\0'){
        count++;}

    printf("Count = %d  \n", count);
    for ( i = 0,j=0 ; i != count; i++){
        if (str[i] == c)
        {
            printf("Found at str[%d] \n", i);
            //    str[i] = '';
        }
        else
        {
            str2[j]=str[i];
            j++ ;
        }
    }

    str2[j]='\0' ;
    printf(" String is = %s", str2);
}

This is the modified version of your code. I've created a new array and placed the rest of the non-matching letters into it. Hope it helps .

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
Benny Dalby
  • 182
  • 4
  • Now consider what happens when presented with a string longer than 99 characters. And equally important, the original string isn't modified at all, therefore defeating the purpose of the function. – WhozCraig Oct 08 '13 at 08:29
  • Yes.It is a valid point.But your input array (the string that holds the original data) has a size of 100.So even if we take the worst case(ie,same String with no match found and 100 characters),the str2 used in the function will not need to hold more than 100 characters rite. – Benny Dalby Oct 08 '13 at 09:31
  • ...and the null terminator ? And note I mentioned a string *longer* than 99 (i.e. `strlen()` reports 100 or more). – WhozCraig Oct 08 '13 at 15:01
0

With

str[i] = "";

you assign the address of the string literal to the char at position i. First of all you should get a warning for that by the compiler because the types are not really compatible; secondly, you would need to either assign a replacement character there, e.g.

str[i] = '_';

or actually remove them by shifting all later characters back (thus overwriting the character to replace).

Joey
  • 344,408
  • 85
  • 689
  • 683