I'm learning C now
I need to make a program that remove char that I'll input from string. I've seen an algorithm and I write this code
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char* pDest = str;
char* pS= str;
printf("sent:\n%s", str);
while (str[i]!='\0'){
if (*pDest != rem) {
*pDest = *pS;
pDest++;
pS++;
}
else if (*pDest == rem) {
pS++;
}
i++;
}
*pDest = '\0';
while (str[i] != '\0') {
printf("number%d", i);
putchar(str[i]);
printf("\n");
i++;
}
}
But it returns nothing, like the value str gets, i think \0 and retuns nothing.
May you help me to find the problem?
Use functions!!
If dest is NULL then this function will modify the string str otherwise, it will place the string with removed ch in dest.
It returns reference to the string with removed character.
char *removeChar(char *dest, char *str, const char ch)
{
char *head = dest ? dest : str, *tail = str;
if(str)
{
while(*tail)
{
if(*tail == ch) tail++;
else *head++ = *tail++;
}
*head = 0;
}
return dest ? dest : str;
}
int main(void)
{
char str[] = "ssHeslsslsos sWossrlssd!ss";
printf("Removal of 's' : `%s`\n", removeChar(NULL, str, 's'));
}
It would be easier to use array style indexing to go through the string. For example use str[i] = str[i + 1] instead of *pstr = *other_pstr. I leave this incomplete method, since this looks like homework.
int main()
{
char str[] = "0123456789";
char ch = '3';
for (int i = 0, len = strlen(str); i < len; i++)
if (str[i] == ch)
{
for (int k = i; k < len; k++)
{
//Todo: shift the characters to left
//Hint, it's one line
}
len--;
}
printf("%s\n", str);
return 0;
}
I just added new char array char dest[MAX_LEN] that store string with deleted symbols:
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char dest[MAX_LEN] = "\0";
char* pDest = dest;
char* pS = str;
printf("sent:\n%s", str);
while (str[i]!='\0')
{
if (*pS != rem)
{
*pDest = *pS;
pDest++;
pS++;
}
else if (*pS == rem)
{
pS++;
}
i++;
}
i = 0;
printf("\nres:\n %s \n", dest);
while (dest[i] != '\0') {
printf("number%d", i);
putchar(dest[i]);
printf("\n");
i++;
}
}
#include <stdio.h>
void revstr(char str[])
{
char temp;
int size = 0;
while(*str != '\0'){
size++;
str++;
}
for (int i = 0; i < size/2; i++)
{
temp = str[i];
str[i] = str[size-1-i];
str[size-1-i] = temp;
}
for(int i = 0; i < size; i++)
{
printf("%c\n", *(str+i));
}
}
int main()
{
char str[20];
printf("enter a string: \n");
scanf("%s", &str);
revstr(str);
return 0;
}
why is my rev string not printing the reverse of the string it is printing out some garbage value.
can you point out why?
After this while loop
while(*str != '\0'){
size++;
str++;
}
the pointer str does not point to the beginning of the string.
Instead you could write for example
while( str[size] != '\0'){
size++;
}
Nevertheless such a function should do only one thing: to reverse a string. It is the caller of the function that decides whether to output the reversed string.
So the function can look like
char * revstr( char s[] )
{
size_t n = 0;
while ( s[n] ) ++n;
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = c;
}
return s;
}
and in main you could write
puts( revstr( str ) );
Here is a demonstrative program.
#include <stdio.h>
char * revstr( char s[] )
{
size_t n = 0;
while ( s[n] ) ++n;
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = c;
}
return s;
}
int main(void)
{
char s[] = "Hello";
puts( s );
puts( revstr( s ) );
return 0;
}
The program output is
Hello
olleH
Of course instead of the while loop you could use the standard string function strlen.
size_t n = strlen( s );
Pay attention to that in the call of scanf
scanf("%s", &str);
the second argument shall be the expression str
scanf("%s", str);
I would implement it another way:
char *reverse(char *str)
{
char *wrk = str, *end = str;
if(str && *str)
{
while(*(end + 1)) end++;
while(end > wrk)
{
char tmp = *end;
*end-- = *wrk;
*wrk++ = tmp;
}
}
return str;
}
It is good to check if the parameter is correct.
I would return the value. It allows you to use the reversed string in expressions and as a function parameter. Example below:
int main(void)
{
char s[] = "Hello world";
printf("%s\n", reverse(s));
}
https://godbolt.org/z/fbo4nsn38
In your code you advance the pointer str to calculate its length but you forgot to reset it to the start after that. Also, your call to scanf should pass str, not its address. Moreover scanf will write beyond the end of str if the user enters a string longer than 19 characters. Try this instead:
#include <stdio.h>
#include <string.h>
void revstr(char str[])
{
char temp;
int size = strlen(str);
for (int i = 0; i < size / 2; i++) {
temp = str[i];
str[i] = str[size - 1 - i];
str[size - 1 - i] = temp;
}
}
int main()
{
char str[20];
printf("enter a string: \n");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';
revstr(str);
printf("%s\n", str);
return 0;
}
Right now I'm working my way through "The C Programming Language" book and boy has it been a humbling experience. Right now I'm working on exercise 2-3 in the book and I can't figure out where I've gone wrong with my squeeze() function. The purpose of the function is to delete any characters in string 1 that are found in string 2. Right now all my function does is delete the first char of string1 if it's found in string2 and then acts strangely after that.. I looked in the answer book and the answer given is very confusing to me. It's hard to make sense of what is being done, so instead of following the logic in the answer book I sort of want to know where I'm going wrong in my own code... Here's the code below:
/* Write an alternate version of squeeze(s1, s2) that deletes each char in s1 that matches
* any char in string s2 */
/* Here's a reference for squeeze(s1, s2):
* squeeze: delete all c from s
*
* void squeeze(char s[], int c)
* {
* int i, j;
*
* for(i = j = 0; s[i] != '\0'; i++)
* if(s[i] != c)
* s[j++] = s[i];
* s[j] = '\0';
* }
*******************************************/
#include <stdio.h>
#include <string.h>
#define MAX_INPUT 100
void squeeze(char string1[], char string2[]);
int main()
{
int c, i = 0, j = 0;
char s1[MAX_INPUT + 2], s2[MAX_INPUT + 2];
printf("\nPlease enter string1\n");
while((c = getchar()) != '\n')
{
s1[i] = c;
i++;
}
s1[i] = '\0';
/* test to see if above worked */
printf("\ns1 = %s\n", s1);
printf("\nPlease enter string2\n");
while((c = getchar()) != '\n')
{
s2[j] = c;
j++;
}
s2[j] = '\0';
/* test to see if above worked */
printf("\ns2 = %s\n", s2);
printf("\nWe will now apply the squeeze function to remove any chars");
printf(" found in string2 from string1\n");
squeeze(s1, s2);
printf("Squeeze(s1, s2) = %s\n", s1);
}
void squeeze(char s1[], char s2[])
{
int i = 0, j = 1; /* for counters */
char temp; /* for char comparison */
temp = s2[0];
while(s2[i] != '\0')
{
if(s1[i] == temp)
{
s1[i] = s1[i+1];
j++;
}
else
{
j++;
}
temp = s2[j];
i++;
}
s1[i+1] = '\0';
}
My output is the following:
Please enter string1
hello
s1 = hello
Please enter string2
help
s2 = help
We will now apply the squeeze function to remove any chars found in string2 from string1
Squeeze(s1, s2) = eello
Can anyone spot what's wrong with my logic? From the answer book I'm guessing I need a third counter, k, somewhere but I can't see a reason for it with the way I programmed the function.. I know I'm missing something though! Thanks so much everyone :)
Answer ( thank you Vlad!) :
void squeeze(char s1[], char s2[])
{
int i = 0, j = 0;
do
{
int k = 0;
while(s2[k] != '\0' && s2[k] != s1[i])
++k;
if (s2[k] == '\0')
{
if ( j != i)
s1[j] = s1[i];
++j;
}
} while (s1[i++] != '\0');
}
Your function does not make a sense.
The while loop is executed according to the length of s2
while(s2[i] != '\0')
However you are using the same index i for checking the string s1.
if(s1[i] == temp)
But the string s1 can be in general shorter or larger than the string s2. So the function can invoke undefined behavior.
Also each character in s1 shall be checked in the string s2 starting from its beginning.
The function can be declared and defined (without using standard C string functions) as it is shown in the demonstrative program below.
#include <stdio.h>
char * squeeze( char s1[], const char s2[] )
{
if ( *s2 != '\0' )
{
size_t i = 0;
size_t j = 0;
do
{
size_t k = 0;
while ( s2[k] != '\0' && s2[k] != s1[i] ) ++k;
if ( s2[k] == '\0' )
{
if ( j != i ) s1[j] = s1[i];
++j;
}
} while ( s1[i++] != '\0' );
}
return s1;
}
int main(void)
{
char s1[] = "Hello World!";
const char *s2 = "aeiou";
puts( s1 );
puts( squeeze( s1, s2 ) );
return 0;
}
The program output is
Hello World!
Hll Wrld!
I used tmp buffer to copy not containing characters. It is simpler and you can check it.
void squeeze(char s1[], char s2[]){
int i, j, k = 0;
char* tmp;
// tmp buffer initial size can be maximum s1 length
tmp = malloc(strlen(s1) + 1);
// loop until s1 character is null
i = 0;
while(s1[i] != '\0'){
// loop until character is found or to the end.
// break if s2 reached to the end or s1[i] == s2[j]
j = 0;
while(s2[j] != '\0' && s2[j] != s1[i]){
j++;
}
// if j reached to the end, add into tmp buffer
if(s2[j] == '\0'){
// set current character
tmp[k] = s1[i];
// increase index
k++;
} else {
printf("Found %c\n", s1[i]);
}
// next character
i++;
}
// last character must be null
tmp[k] = '\0';
// tmp copy to s1
strcpy(s1, tmp);
// free tmp buffer
free(tmp);
}
#include <stdio.h>
#include <string.h>
#define SIZE 40
int main(void)
{
char buffer1[SIZE] = "computer program";
char *ptr;
int ch = 'p', j = 0, i;
for (i = 0; i<strlen(buffer1); i++)
{
ptr = strchr(buffer1[i], ch);
if (ptr != 0) j++;
printf(" %d ", j);
}
}
I want to count how many times a character occurs in a string.
In my program I chose the character 'p'.
I know Pascal, I am learning C now. In pascal is a function called Pos(x,y) which is searching for x in y. Is something familiar to this? I think what I used here is not.
The function signature of strchr is
char *strchr(const char *s, int c);
You need to pass a char* but you have passed a char. This is wrong.
You have used the strlen in loop - making it inefficient. Just calculate the length of the string once and then iterate over it.
char *t = buffer;
while(t!= NULL)
{
t = strchr(t, ch);
if( t ) {
t++;
occurences++;
}
}
And without using standard library functions you can simply loop over the char array.
size_t len = strlen(buffer);
for(size_t i = 0; i < len; i++){
if( ch == buffer[i]) occurences++;
}
Or alternatively without using strlen
char *p = buffer;
while(*p){
if( *p == ch ){
occurences++;
}
p++;
}
Or
for(char *p = buffer; *p; occurences += *p++ == ch);
Try this example :
int main()
{
char buffer1[1000] = "computer program";
char ch = 'p';
int i, frequency = 0;
for(i = 0; buffer1[i] != '\0'; ++i)
{
if(ch == buffer1[i])
++frequency;
}
printf("Frequency of %c = %d", ch, frequency);
return 0;
}
How do I remove a character from a string?
If I have the string "abcdef" and I want to remove "b" how do I do that?
Removing the first character is easy with this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[] = "abcdef";
char word2[10];
strcpy(word2, &word[1]);
printf("%s\n", word2);
return 0;
}
and
strncpy(word2, word, strlen(word) - 1);
will give me the string without the last character, but I still didn't figure out how to remove a char in the middle of a string.
memmove can handle overlapping areas, I would try something like that (not tested, maybe +-1 issue)
char word[] = "abcdef";
int idxToDel = 2;
memmove(&word[idxToDel], &word[idxToDel + 1], strlen(word) - idxToDel);
Before: "abcdef"
After: "abdef"
Try this :
void removeChar(char *str, char garbage) {
char *src, *dst;
for (src = dst = str; *src != '\0'; src++) {
*dst = *src;
if (*dst != garbage) dst++;
}
*dst = '\0';
}
Test program:
int main(void) {
char* str = malloc(strlen("abcdef")+1);
strcpy(str, "abcdef");
removeChar(str, 'b');
printf("%s", str);
free(str);
return 0;
}
Result:
>>acdef
My way to remove all specified chars:
void RemoveChars(char *s, char c)
{
int writer = 0, reader = 0;
while (s[reader])
{
if (s[reader]!=c)
{
s[writer++] = s[reader];
}
reader++;
}
s[writer]=0;
}
char a[]="string";
int toBeRemoved=2;
memmove(&a[toBeRemoved],&a[toBeRemoved+1],strlen(a)-toBeRemoved);
puts(a);
Try this . memmove will overlap it.
Tested.
Really surprised this hasn't been posted before.
strcpy(&str[idx_to_delete], &str[idx_to_delete + 1]);
Pretty efficient and simple. strcpy uses memmove on most implementations.
int chartoremove = 1;
strncpy(word2, word, chartoremove);
strncpy(((char*)word2)+chartoremove, ((char*)word)+chartoremove+1,
strlen(word)-1-chartoremove);
Ugly as hell
The following will extends the problem a bit by removing from the first string argument any character that occurs in the second string argument.
/*
* delete one character from a string
*/
static void
_strdelchr( char *s, size_t i, size_t *a, size_t *b)
{
size_t j;
if( *a == *b)
*a = i - 1;
else
for( j = *b + 1; j < i; j++)
s[++(*a)] = s[j];
*b = i;
}
/*
* delete all occurrences of characters in search from s
* returns nr. of deleted characters
*/
size_t
strdelstr( char *s, const char *search)
{
size_t l = strlen(s);
size_t n = strlen(search);
size_t i;
size_t a = 0;
size_t b = 0;
for( i = 0; i < l; i++)
if( memchr( search, s[i], n))
_strdelchr( s, i, &a, &b);
_strdelchr( s, l, &a, &b);
s[++a] = '\0';
return l - a;
}
This is an example of removing vowels from a string
#include <stdio.h>
#include <string.h>
void lower_str_and_remove_vowel(int sz, char str[])
{
for(int i = 0; i < sz; i++)
{
str[i] = tolower(str[i]);
if(str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u')
{
for(int j = i; j < sz; j++)
{
str[j] = str[j + 1];
}
sz--;
i--;
}
}
}
int main(void)
{
char str[101];
gets(str);
int sz = strlen(str);// size of string
lower_str_and_remove_vowel(sz, str);
puts(str);
}
Input:
tour
Output:
tr
Use strcat() to concatenate strings.
But strcat() doesn't allow overlapping so you'd need to create a new string to hold the output.
I tried with strncpy() and snprintf().
int ridx = 1;
strncpy(word2,word,ridx);
snprintf(word2+ridx,10-ridx,"%s",&word[ridx+1]);
Another solution, using memmove() along with index() and sizeof():
char buf[100] = "abcdef";
char remove = 'b';
char* c;
if ((c = index(buf, remove)) != NULL) {
size_t len_left = sizeof(buf) - (c+1-buf);
memmove(c, c+1, len_left);
}
buf[] now contains "acdef"
This might be one of the fastest ones, if you pass the index:
void removeChar(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
This code will delete all characters that you enter from string
#include <stdio.h>
#include <string.h>
#define SIZE 1000
char *erase_c(char *p, int ch)
{
char *ptr;
while (ptr = strchr(p, ch))
strcpy(ptr, ptr + 1);
return p;
}
int main()
{
char str[SIZE];
int ch;
printf("Enter a string\n");
gets(str);
printf("Enter the character to delete\n");
ch = getchar();
erase_c(str, ch);
puts(str);
return 0;
}
input
a man, a plan, a canal Panama
output
A mn, pln, cnl, Pnm!
Edit : Updated the code zstring_remove_chr() according to the latest version of the library.
From a BSD licensed string processing library for C, called zString
https://github.com/fnoyanisi/zString
Function to remove a character
int zstring_search_chr(char *token,char s){
if (!token || s=='\0')
return 0;
for (;*token; token++)
if (*token == s)
return 1;
return 0;
}
char *zstring_remove_chr(char *str,const char *bad) {
char *src = str , *dst = str;
/* validate input */
if (!(str && bad))
return NULL;
while(*src)
if(zstring_search_chr(bad,*src))
src++;
else
*dst++ = *src++; /* assign first, then incement */
*dst='\0';
return str;
}
Exmaple Usage
char s[]="this is a trial string to test the function.";
char *d=" .";
printf("%s\n",zstring_remove_chr(s,d));
Example Output
thisisatrialstringtotestthefunction
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
void dele_char(char s[],char ch)
{
int i,j;
for(i=0;s[i]!='\0';i++)
{
if(s[i]==ch)
{
for(j=i;s[j]!='\0';j++)
s[j]=s[j+1];
i--;
}
}
}
int main()
{
char s[MAX],ch;
printf("Enter the string\n");
gets(s);
printf("Enter The char to be deleted\n");
scanf("%c",&ch);
dele_char(s,ch);
printf("After Deletion:= %s\n",s);
return 0;
}
#include <stdio.h>
#include <string.h>
int main(){
char ch[15],ch1[15];
int i;
gets(ch); // the original string
for (i=0;i<strlen(ch);i++){
while (ch[i]==ch[i+1]){
strncpy(ch1,ch,i+1); //ch1 contains all the characters up to and including x
ch1[i]='\0'; //removing x from ch1
strcpy(ch,&ch[i+1]); //(shrinking ch) removing all the characters up to and including x from ch
strcat(ch1,ch); //rejoining both parts
strcpy(ch,ch1); //just wanna stay classy
}
}
puts(ch);
}
Let's suppose that x is the "symbol" of the character you want to remove
,my idea was to divide the string into 2 parts:
1st part will countain all the characters from the index 0 till (and including) the target character x.
2nd part countains all the characters after x (not including x)
Now all you have to do is to rejoin both parts.
This is what you may be looking for while counter is the index.
#include <stdio.h>
int main(){
char str[20];
int i,counter;
gets(str);
scanf("%d", &counter);
for (i= counter+1; str[i]!='\0'; i++){
str[i-1]=str[i];
}
str[i-1]=0;
puts(str);
return 0;
}
I know that the question is very old, but I will leave my implementation here:
char *ft_strdelchr(const char *str,char c)
{
int i;
int j;
char *s;
char *newstr;
i = 0;
j = 0;
// cast to char* to be able to modify, bc the param is const
// you guys can remove this and change the param too
s = (char*)str;
// malloc the new string with the necessary length.
// obs: strcountchr returns int number of c(haracters) inside s(tring)
if (!(newstr = malloc(ft_strlen(s) - ft_strcountchr(s, c) + 1 * sizeof(char))))
return (NULL);
while (s[i])
{
if (s[i] != c)
{
newstr[j] = s[i];
j++;
}
i++;
}
return (newstr);
}
just throw to a new string the characters that are not equal to the character you want to remove.
Following should do it :
#include <stdio.h>
#include <string.h>
int main (int argc, char const* argv[])
{
char word[] = "abcde";
int i;
int len = strlen(word);
int rem = 1;
/* remove rem'th char from word */
for (i = rem; i < len - 1; i++) word[i] = word[i + 1];
if (i < len) word[i] = '\0';
printf("%s\n", word);
return 0;
}
This is a pretty basic way to do it:
void remove_character(char *string, int index) {
for (index; *(string + index) != '\0'; index++) {
*(string + index) = *(string + index + 1);
}
}
I am amazed none of the answers posted in more than 10 years mention this:
copying the string without the last byte with strncpy(word2, word, strlen(word)-1); is incorrect: the null terminator will not be set at word2[strlen(word) - 1]. Furthermore, this code would cause a crash if word is an empty string (which does not have a last character).
The function strncpy is not a good candidate for this problem. As a matter of fact, it is not recommended for any problem because it does not set a null terminator in the destination array if the n argument is less of equal to the source string length.
Here is a simple generic solution to copy a string while removing the character at offset pos, that does not assume pos to be a valid offset inside the string:
#include <stddef.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t i;
for (i = 0; i < pos && src[i] != '\0'; i++) {
dest[i] = src[i];
}
for (; src[i] != '\0'; i++) {
dest[i] = src[i + 1];
}
dest[i] = '\0';
return dest;
}
This function also works if dest == src, but for removing the character in place in a modifiable string, use this more efficient version:
#include <stddef.h>
char *removeat_in_place(char *str, size_t pos) {
size_t i;
for (i = 0; i < pos && str[i] != '\0'; i++)
continue;
for (; str[i] != '\0'; i++)
str[i] = str[i + 1];
return str;
}
Finally, here are solutions using library functions:
#include <string.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t len = strlen(src);
if (pos < len) {
memmove(dest, src, pos);
memmove(dest + pos, src + pos + 1, len - pos);
} else {
memmove(dest, src, len + 1);
}
return dest;
}
char *removeat_in_place(char *str, size_t pos) {
size_t len = strlen(str);
if (pos < len) {
memmove(str + pos, str + pos + 1, len - pos);
}
return str;
}
A convenient, simple and fast way to get rid of \0 is to copy the string without the last char (\0) with the help of strncpy instead of strcpy:
strncpy(newStrg,oldStrg,(strlen(oldStrg)-1));