how to remove a character from a string

T

Toto

Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.
 
A

Arthur J. O'Dwyer

I have the following string:
"table+camera"
and I want to remove the + sign:
"tablecamera".

How do i do that ?


#include <string.h>

char s[] = "table+camera";
char *p;

while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

Make sure to read the FAQ on string manipulation, too.

HTH,
-Arthur
 
C

Christopher Benson-Manica

Toto said:
"table+camera"
and I want to remove the + sign:
"tablecamera".

Well, I hope this isn't a homework question, because I'll post an
answer:

void rem_char( char *s, char t )
{
if( !s || !*s ) return;

while( *s++ != t ) if( !*s ) return;
while( *(s-1)=*s++ );
}

I don't guarantee that it's conforming, but it produced correct
results for me.
 
E

Eric Sosman

Arthur J. O'Dwyer said:
I have the following string:
"table+camera"
and I want to remove the + sign:
"tablecamera".

How do i do that ?

#include <string.h>

char s[] = "table+camera";
char *p;

while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

This is only guaranteed to work if the '+' is the
last character in the string. Otherwise the source and
destination overlap, which is a no-no for strcpy(). A
safe alternative is

memmove(p, p+1, strlen(p+1)+1);

.... which can be simplified to

memmove(p, p+1, strlen(p));

Also, the Little Tin God might be better propitiated
by replacing the `while' with

p = s;
while ((p = strchr(p, '+')) != NULL)

.... thus not searching and re-searching and re-re-searching
parts of `s' already known to be free of '+' characters.
 
E

Eric Sosman

Eric said:
Arthur J. O'Dwyer said:
while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

This is only guaranteed to work if the '+' is the
last character in the string. [...]

And now that I think about it, not even then.
 
M

Martin Dickopp

Arthur J. O'Dwyer said:
I have the following string:
"table+camera"
and I want to remove the + sign:
"tablecamera".

How do i do that ?


#include <string.h>

char s[] = "table+camera";
char *p;

while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

7.21.2.3#2 (strcpy): "[...] If copying takes place between objects that
overlap, the behavior is undefined."

(Your algorithm is also inefficient, because it scans `s' from the
beginning after replacing each '+' character.)

I suggest the following:

char s [] = "table+camera";
const char *src = s;
char *dst = s;

do
{
while (*src == '+')
++src;
}
while ((*dst++ = *src++) != '\0');

Martin
 
C

code_wrong

Toto said:
Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.

#define MAX_LEN 1000

char input_string[MAX_LEN];
char output_string[MAX_LEN];

strcpy(input_string, "table+camera");
int len = strlen(input_string);
int j =0;
for(int i =0; i<=len; i++)/*we wanna copy the null terminator*/
{
if(input_string != '+')
{
output_string[j] = input_string;
j++;
}
}
 
J

Joe Wright

Toto said:
Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.
#include <stdio.h>
#include <string.h>

int main(void) {
char string[] = "table+camera";
char *s;
int i;
puts(string);
s = strchr(string, '+');
i = s - string + 1;
while ((*s++ = string[i++])) ;
puts(string);
return 0;
}

Try this.
 
P

pete

Toto said:
Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.

/* BEGIN new.c */

#include <stdio.h>

#define STRING "table+camera"
#define WHITE "+"

char *str_squeeze(char *, const char *);
char *str_tok_r(char *, const char *, char **);
size_t str_spn(const char *, const char *);
size_t str_cspn(const char *, const char *);
char *str_chr(const char *, int);
char *str_cpy(char *, const char *);

int main(void)
{
const char *const original = STRING;
char s1[sizeof STRING];

puts(str_squeeze(str_cpy(s1, original), WHITE));
return 0;
}

char *str_squeeze(char *s1, const char *s2)
{
char *p3;
char const *const p2 = s2;
char *const p1 = s1;

s2 = str_tok_r(p1, p2, &p3);
while (s2 != NULL) {
while (*s2 != '\0') {
*s1++ = *s2++;
}
s2 = str_tok_r(NULL, p2, &p3);
}
*s1 = '\0';
return p1;
}

char *str_tok_r(char *s1, const char *s2, char **p1)
{
if (s1 != NULL) {
*p1 = s1;
}
s1 = *p1 + str_spn(*p1, s2);
if (*s1 == '\0') {
return NULL;
}
*p1 = s1 + str_cspn(s1, s2);
if (**p1 != '\0') {
*(*p1)++ = '\0';
}
return s1;
}

size_t str_spn(const char *s1, const char *s2)
{
size_t n;

for (n = 0; *s1 != '\0' && str_chr(s2, *s1) != NULL; ++s1) {
++n;
}
return n;
}

size_t str_cspn(const char *s1, const char *s2)
{
size_t n;

for (n = 0; str_chr(s2, *s1) == NULL; ++s1) {
++n;
}
return n;
}

char *str_chr(const char *s, int c)
{
while (*s != (char)c) {
if (*s == '\0') {
return NULL;
}
++s;
}
return (char *)s;
}

char *str_cpy(char *s1, const char *s2)
{
char *const p1 = s1;

do {
*s1 = *s2++;
} while (*s1++ != '\0');
return p1;
}

/* END new.c */
 
M

Mac

Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.

Use strchr() to find the character. Use memmove() to copy over it. If you
want to replace more than one instance of the character, do this
repeatedly until strchr() returns NULL.

If there is any chance that the string is long, be sure to avoid
re-searching the whole string for the character.

HTH

--Mac
 
C

CBFalconer

Arthur J. O'Dwyer said:
I have the following string:
"table+camera"
and I want to remove the + sign:
"tablecamera".

How do i do that ?

#include <string.h>

char s[] = "table+camera";
char *p;

while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);
Description

[#2] The strcpy function copies the string pointed to by s2
(including the terminating null character) into the array
pointed to by s1. If copying takes place between objects
that overlap, the behavior is undefined.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
try:
#include <string.h>

char s[] = "table+camera";
char *p, *pp;

while ((p = strchr(s, '+'))) {
pp = p + 1;
while (*p++ = *pp++) continue;
}
Make sure to read the FAQ on string manipulation, too.

Here we agree :)
 
C

Chris Torek

Also, the Little Tin God might be better propitiated
by replacing the `while' with

p = s;
while ((p = strchr(p, '+')) != NULL)

... thus not searching and re-searching and re-re-searching
parts of `s' already known to be free of '+' characters.

Of course, if one is bowing to this Little Tin God, one might want
to consider removing "+" characters from the back end first, so
that in:

this+that++some+other+stuff

you never copy any of the "+" characters. But then it might be
important to move every character at most once, which requires
counting up all the "+" characters up front, and ... :)

Seriously though, one "backwards loop" version:

size_t len = strlen(s);
size_t i, j, n;

for (i = len; i > 0;) {
for (j = i; i > 0 && s[i - 1] == '+'; i--)
continue;
n = j - i;
if (n) {
/*
* There were some '+' characters (n in a row) that we
* would like to remove. Once they are removed, the
* string will be n bytes shorter. The last such '+'
* character is at s, i.e., we wish to keep s[i-1]
* unchanged (if it even exists) but clobber s.
*
* s[j] is not a '+' -- either it is a wanted character
* or it is the '\0' byte (j==len). Copying (len-j)+1
* bytes copies the '\0' too; we could copy just len-j
* but then we would have to re-terminate the string
* eventually (see below).
*/
memmove(&s, &s[j], len - j + 1);
len -= n;
}
}
/* s[len] = 0; -- do this only if we memmove() len-j without the +1 */

The code above is quite untested. :)
 
2

(2B) || !(2B)

Toto said:
Hello,
my problem is quite simple to explain.
I have the following string:

"table+camera"

and I want to remove the + sign:
"tablecamera".

How do i do that ?
Thanks for your help.

#include <stdio.h>


int
main(void)
{
char *s="table+camera+chair";
char *p,*temp,c;
for(p=s,temp=s;c=*temp;temp++)
{
if(c != '+') *p++=c;
}
*p=0;
printf("%s",s);
return 0;
}
 
O

Old Wolf

Martin Dickopp said:
Arthur J. O'Dwyer said:
#include <string.h>

char s[] = "table+camera";
char *p;

while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

7.21.2.3#2 (strcpy): "[...] If copying takes place between objects that
overlap, the behavior is undefined."

I don't like this (although I'm sure it is correct). I have always
been in the habit of feeling safe about strcpy, strncpy, *printf,
memcpy, etc. as long as dst < src , and using memmove or some other
technique if dst > src.
I suggest the following: [snip]
while ((*dst++ = *src++) != '\0');

Some C-teaching books have used exactly that as the
implementation of strcpy (with some extra code to return the
correct return value, of course). It is unfortunate that it
is OK to write this out, but not OK to call strcpy !
 
I

Irrwahn Grausewitz

Martin Dickopp said:
"Arthur J. O'Dwyer" <[email protected]> writes:
while ((p = strchr(s,'+')) != NULL)
strcpy(p, p+1);

7.21.2.3#2 (strcpy): "[...] If copying takes place between objects that
overlap, the behavior is undefined."

I don't like this (although I'm sure it is correct). I have always
been in the habit of feeling safe about strcpy, strncpy, *printf,
memcpy, etc. as long as dst < src , and using memmove or some other
technique if dst > src.

Bad habit. Bad, bad habit. ;-)
I suggest the following: [snip]
while ((*dst++ = *src++) != '\0');

Some C-teaching books have used exactly that as the
implementation of strcpy (with some extra code to return the
correct return value, of course). It is unfortunate that it
is OK to write this out, but not OK to call strcpy !

The rationale however is clear: the standard imposes no detailed
requirements on the internals of strcpy to allow RealWorld[tm]
implementations to use the underlying platform's most efficient way
to copy the data. To stay on the safe side use memmove, which
is explicitly required to copy data between overlapping objects.

Just to add that Martin's solution avoids multiple data movement in
case the string contains more than one instance of the character to
delete.

That said, the following version _might_ perform _slightly_ better,
if the passed string has a long initial (or consists entirely of a)
sequence not containing the character to delete:

char *igStrsqz( char *str, int ch )
{
char *dst = strchr( str, ch );

if ( dst != NULL )
{
const char *src = dst;
while ( *dst != '\0' )
{
while ( *src == ch )
src++;
*dst++ = *src++;
}
}
return str;
}

Regards
 
G

goose

(2B) || !(2B) said:
#include <stdio.h>


int
main(void)
{
char *s="table+camera+chair";

ITYM:
char s[]="table+camera+chair";
char *p,*temp,c;
for(p=s,temp=s;c=*temp;temp++)
{
if(c != '+') *p++=c;
}
*p=0;
printf("%s",s);
return 0;
}

regards,
goose
 
C

CBFalconer

Chris said:
Of course, if one is bowing to this Little Tin God, one might want
to consider removing "+" characters from the back end first, so
that in:

this+that++some+other+stuff

you never copy any of the "+" characters. But then it might be
important to move every character at most once, which requires
counting up all the "+" characters up front, and ... :)
.... snip ...

An untested nocount version, returning revised strlen, might be:

size_t str_strip(char *s, char x)
{
char *si, *d;

si = d = s;
while ((*d = *s++))
if (*d != x) d++;
return (d - si);
} /* str_strip */
 
B

brian

may be use sed....

sed 's/+//g' file

where file is the file containing your input strings like table+camera etc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top