How can I replace a letter in a char array in c? - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char first[15];
printf("\n\tWrite here your code");
scanf("%s",first);
if()//there is "n" in the char
//change n with 1
else
//quit
return 0;
}

Replace character with character
This code will replace every occurrence of the character 'n' with the character '1'.
#include <stdio.h>
int main(void)
{
char str[15];
printf("Input: ");
scanf("%14s", str); // prevent buffer overflow
for (int i = 0; str[i]; ++i) { // iterate over str
if (str[i] == 'n')
str[i] = '1';
}
printf("Modified: %s\n", str);
return 0;
}
Replace character with string
This code will replace every occurrence of the character 'n' with the string "1+k" using the function strcat. The modified string is saved to char mod[].
#include <stdio.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char str[15];
printf("Input: ");
scanf("%14s", str); // prevent buffer overflow
char mod[] = "";
for (int i = 0; str[i]; ++i) { // iterate over str
if (str[i] == 'n') {
char *repl = "1+k";
strcat(mod, repl); // add "1+k" to mod
} else {
strncat(mod, &str[i], 1); // add str[i] to mod
}
}
printf("Modified: %s\n", mod);
return 0;
}

Such a trivial question deserves a non trivial answer
Note that this approach with branching, demonstrated by #Andy Sukowski-Bang, is - when compiled with -O3 - roughly 6.5x time slower than my approach, illustratating the efficiency of bitwise operations over branching instructions (not to mention Meltdown and Spectre vulnerabilities and its on branching if mitigations are enabled).
The following program will convert every occurence of the letter from to the designated letter.
It is able to replace all characters from 'A' to 'z' to '8' in a string of 8,286,208 bytes in only 0.07s:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
// gcc -O3 replace.c && ./a.out
void replace(char *s, char from, char to, long n) {
char eq;
while (n--) {
eq = !(*s ^ from);
*s = !eq * *s + eq * to;
s++;
}
}
void replace_branching(char *s, char from, char to, long n) {
while (n--) {
if (*s == from)
*s = to;
s++;
}
}
void read_file_to_buffer(FILE *f, long length) {
char buffer[length + 1];
fseek(f, 0, SEEK_SET);
void (*fptr[2]) (char *s, char from, char to, long n) = {replace_branching, replace};
if (fread (buffer, 1, length, f) ) {
buffer[length] = '\0';
fclose (f);
char subbuff[33];
subbuff[32] = '\0';
char from = 'A';
char to = '8';
clock_t start, end;
double cpu_time_used[2];
for (int j = 0; j < 2; j++){
start = clock();
for (int i = 0; i < 0x20 + 26; i++) {
fptr[j](buffer, from + i, to, length);
//memcpy( subbuff, &buffer[0], 32 );
//printf("Modified: %s\n", subbuff);
}
end = clock();
cpu_time_used[j] = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Time: %fs\n", cpu_time_used[j]);
}
printf("Without branching it is %fx faster\n", cpu_time_used[0] / cpu_time_used[1]);
}
}
int main(void)
{
FILE * f;
long length;
if ((f = fopen ("test.txt", "rb"))) // NB: test.txt is a file of 8,286,208 bytes
{
fseek (f, 0, SEEK_END);
read_file_to_buffer(f, ftell(f));
}
return 0;
}
/*
Time: 0.475005s
Time: 0.070859s
Without branching it is 6.703524x faster
*/
Some explanations
eq = !(*s ^ from); // eq will equal 0 if letters are same, else it will equal 1
*s = !eq * *s + eq * to; // we assign to the pointer its same old value with !eq if the character 'from' was absent, else we will assign the character 'to'.
PS: No malloc were used, I used VLA and it is bad, very bad, don't do this at home!

Related

My invertString function doesn't seem to work properly

So, I have to solve the problem above. I have written some code in C, but the compiler doesn't give me any outputs. Here's the code below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void invertString(char *s1, char **s2);
void invertString(char *s1, char **s2){
int len = strlen(s1);
*s2 = (char*)malloc((len+1) * sizeof(char));
int start = 0;
int end = 0;
int index = 0;
while (end < len){
while(s1[end]<s1[end+1] && end < len-1)
end++;
for (int i=end;i>=start;i--)
(*s2)[index]=s1[i];
index++;
start = end + 1;
while(s1[end]>=s1[end+1] && end < len-1){
(*s2)[index]=s1[end];
index++;
end++;
start = end;
}
}
(*s2)[index] = '\0';
}
int main() {
char s1[] = "A B C D D D D Z Y X W E F G";
char *s2 = NULL;
invertString(s1, &s2);
printf("Input string: %s\n", s1);
printf("Output string: %s\n", s2);
free(s2);
return 0;
}`
I was expecting the code to output the string such that the substrings in ascending order would be reversed to descending, while the rest of the string would remain the same. Instead, I receive no output. I think the function is stuck in a loop because when I try to re-run, it says the function is already running.
Turns out that because my input string had spaces between all letters, my traverser was completely useless. I had to either iterate +2 every time or delete all spaces in the input. This updated code works fine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void invertString(char *s1, char **s2);
void invertString(char *s1, char **s2){
int len = strlen(s1);
*s2 = (char*)malloc((len) * sizeof(char));
int start = 0;
int end = 0;
int index = 0;
while (end < len){
printf("%d%d\n", end, len);
while(s1[end]<s1[end+1])
end++;
for (int i=end;i>=start;i--){
(*s2)[index]=s1[i];
index++;
}
end++;
start = end;
while(s1[end]>=s1[end+1]){
(*s2)[index]=s1[end];
index++;
end++;
start = end;
}
}
(*s2)[index] = '\0';
}
int main() {
char s1[] = "ABCDDDDZYXWEFG";
char *s2 = NULL;
invertString(s1, &s2);
printf("Input string: %s\n", s1);
printf("Output string: %s\n", s2);
free(s2);
return 0;
}
Code accesses outside array bounds.
Viewable with some tests using OP's corrected code.
Last error certainly due to insufficient allocation.
// *s2 = (char*)malloc((len) * sizeof(char));
*s2 = malloc((len + 1u) * sizeof(char));
Note: char may be negative.
Perhaps additional errors.
void invertString(char *s1, char **s2){
int len = strlen(s1);
*s2 = (char*)malloc((len) * sizeof(char));
int start = 0;
int end = 0;
int index = 0;
while (end < len){
printf("%d%d\n", end, len);
while(s1[end]<s1[end+1])
end++;
for (int i=end;i>=start;i--){
(*s2)[index]=s1[i];
index++;
}
end++;
start = end;
if (end + 1 > len) {
fprintf(stderr, "%d %d %d\n", __LINE__, end + 1, len);
//exit(-1);
}
while(s1[end]>=s1[end+1]){
(*s2)[index]=s1[end];
index++;
end++;
start = end;
}
}
if (index >= len) {
fprintf(stderr, "%d %d %d\n", __LINE__, index, len);
exit(-1);
}
(*s2)[index] = '\0';
}

How do I make the strlen() function not count spaces?

#include <stdio.h>
#include <string.h>
int main(void) {
char string[1024];
int len = 0;
int i = 0;
while (fgets(string, sizeof(string), stdin) != 0);
len = strlen(string) - 1;
if (len % 2 == 0) {
printf("%s", string);
}
}
The aim of this code is to print out inputs that have an even number of characters and omit anything else (will not print it). The program works when there is no space in the string however once I place a space it counts it as the length which I'm trying to stop. How do I make this program omit spaces when counting the length of the string?
How do I make the strlen() function not count spaces?
The standard function strlen() simple does not do that. Easy to code a new function that does.
#include <ctype.h>
#include <stddef.h>
size_t spaceless_strlen(const char *s) {
size_t len = 0;
const unsigned char *us = (const unsigned char *) s;
while (*us) {
if (*us != ' ') len++;
// Or if not counting white-spaces
if (!isspace(*us)) len++;
us++;
}
return len;
}
Best to pass unsigned char values to is...() functions so a unsigned char * pointer was used.
The trick is to only count characters you want. strlen() counts all characters. Write yourself a function:
#include <string.h>
size_t count( const char * s, int (*f)( int ) )
//
// Return the number of elements in the c-string
// `s` that satisfy the predicate function `f()`.
// The function type matches the Standard Library
// character classification functions in <ctype.h>.
{
size_t result = 0;
while (*s) result += f( *s++ );
return result;
}
With that in hand, you need a predicate function that will return 1 for non-whitespace characters, and 0 for whitespace characters. Easy enough:
#include <ctype.h>
int not_isspace( int c )
{
return !isspace( c );
}
Now you can totally count the number of non-whitespace characters in your string:
int length = count( s, &not_isspace );
That’s it!
Regarding how you can achieve counting characters that are not spaces, you can try this.
#include <stdio.h>
#include <string.h>
int main(void) {
char string[1024];
int len;
int count=0;
int i;
while (fgets(string, sizeof(string), stdin) != 0){
len = strlen(string) ;
for (i=0; i<len;i++)
{
if (string[i]!=' ')
count++;
}
if (count % 2 == 0)
{
printf("%s", string);
}
}
return 0;
}
Note: In my opinion, this isn't the most optimal way to achieve so but I tried to keep it based on your code and logic!
This seems better :
EDIT : it is if you replace the get function with fgets as you initially did!
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[1024];
int i=0,count=0;
printf("Enter a String\n");
gets(str);
while(str[i]!='\0')
{
if(str[i]!=' ')
{
count++;
}
i++;
}
if(count% 2 ==0)
{
printf("%s ",str,);
}
return 0;
}
It is possible to make a dedicated function using fgetc() instead of calling fgets() which returns the read string and its length (without counting the spaces):
#include <stdio.h>
#include <string.h>
#include <ctype.h>
static int my_fgets(char *s, int size, FILE *stream)
{
char c;
int len;
char *in;
if (!s || (size <= 0)) {
return 0;
}
len = 0;
in = s;
do {
c = fgetc(stream);
if ((len < (size - 1)) && (c != EOF) && (c != '\n')) {
if (!isspace(c)) {
len ++;
}
*(in ++) = c;
}
} while ((len < (size - 1)) && (c != EOF) && (c != '\n'));
*in = '\0';
return len;
}
int main(void) {
char string[1024];
int len = 0;
int i = 0;
len = my_fgets(string, sizeof(string), stdin);;
if (len % 2 == 0) {
printf("%s, len=%d\n", string, len);
}
}
If you aren't super-concerned about performance, the easiest to read version might be to call strchr repeatedly in a loop, count the spaces and then subtract them from the string length. Example:
size_t spaceout (const char* original)
{
size_t spaces = 0;
for(char* str=strchr(original,' '); str!=NULL; str=strchr(str+1,' '))
{
spaces++;
}
return strlen(original) - spaces;
}
This only looks for ' ' and it actually iterates over the string twice because of the final strlen call. But the code is quite easy to read.
A possible micro-optimization would be to pass the string length as parameter in case the caller already knows it.

Trying to "copy" one string in reverse

I've been trying to "copy" one string to another, in reverse.
It kindof works, but it prints some weird symbols.
I've tried setting char copy[length2] but that makes the program not run at all.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 50
int main()
{
char string[ARR_SIZE];
printf("Enter char array!\n");
fgets(string, ARR_SIZE, stdin);
string[strlen(string) - 1] = '\0';
int length = (strlen(string) - 1);
int length2 = (strlen(string) - 1);
printf("%s\t%d\n", string, length);
for (int i = 0; i <= length; i++)
{
printf("INDEX = %d CHAR = %c\n", i, string[i]);
}
printf("%d", length2);
char copy[ARR_SIZE];
for (int i = 0; i <= length2; i++)
{
copy[i] = string[length];
length--;
}
printf("\n%s", copy);
}
These are the minimal modifications I'd make to your code:
#include <stdio.h>
#include <string.h>
// remove unneeded headers
#define ARR_SIZE 50
int main(void)
{
char string[ARR_SIZE];
printf("Enter char array!\n");
fgets(string, ARR_SIZE, stdin);
string[strlen(string) - 1] = '\0';
// remove the -1 on the string length calculation, the NUL terminator is not
// included in strlen's return value
int length = strlen(string);
// no sense in calling strlen twice
int length2 = length;
// fixed `length` now prints the correct length
printf("%s\t%d\n", string, length);
// change from <= to <. The array indices where the characters live are
// [0, length-1].
for (int i = 0; i < length; i++)
{
printf("INDEX = %d CHAR = %c\n", i, string[i]);
}
// fixed `length2` now prints the correct length
printf("%d", length2);
char copy[ARR_SIZE];
for (int i = 0; i < length2; i++)
{
// last character in `string` lives at the `length`-1 index
copy[i] = string[length-1];
length--;
}
// `length2` is the index after the last char in `copy`, this needs
// to be NUL terminated.
copy[length2] = '\0';
// prints the reversed string
printf("\n%s", copy);
}
Demo
Use functions.
Terminate strings with null character \0 or simply 0.
char *copyreverse(char *dest, const char *src)
{
size_t len = strlen(src);
const char *end = src + len - !!len;
char *wrk = dest;
while(len--)
*wrk++ = *end--;
*wrk = 0;
return dest;
}
int main()
{
char dest[10];
char *src = "hello";
printf("`%s` reversed `%s`\n", src, copyreverse(dest, src));
}

Program prints unrelated chars

I wanted to split an array to 2 arrays that the first one contains the lowercased letters of the original array and the second one contains the uppercased letters and from some reason it prints some unrelated chars.
#include <stdio.h>
#include <string.h>
#define LEN 8
int main(void)
{
char str[] = "SHaddOW";
char smallStr[LEN], bigStr[LEN];
int i = 0;
int indexSmall = 0;
int indexBig = 0;
for (i = 0; i <= LEN; i++)
{
if (str[i] <= 'Z')
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
if (str[i] >= 'Z')
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
printf("1: ");
puts(smallStr);
printf("2: ");
puts(bigStr);
system("PAUSE");
return 0;
}
Don't define length before you create the string to test.
Create it's length after defining the string to test.
Copy the characters as you encounter them, but as #Ed Heal says you must add a null terminator so that you can print out the two strings (they aren't really strings until they are null terminated).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (void)
{
char str[] = "SHaddOW";
int len = strlen(str) +1;
char smallStr[len], bigStr[len];
char term[] = {'\0'};
int n, s, b;
s=0;
b=0;
for(n=0; n<len; n++) {
if(islower(str[n])) {
memcpy(smallStr +s, str +n, 1);
s++;
} else if (isupper(str[n])){
memcpy(bigStr +b, str +n, 1);
b++;
}
}
memcpy(smallStr + s, term, 1);
memcpy(bigStr + b , term, 1 );
printf("Upper: %s\n", bigStr);
printf("Lower: %s\n", smallStr);
}
Output:
Upper: SHOW
Lower: add
Add this to the if structure (and other code to support it)
} else {
memcpy(anyStr +a, str +n, 1);
a++;
}
then:
char str[] = ".S1H2a3d4d5O6W.";
and:
printf("Anything else: %s\n", anyStr);
returns:
Upper: SHOW
Lower: add
Anything else: .123456.
A more compact approach with (perhaps) more meaningful variable names:
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
int main ( void ) {
const char str[] = "SHaddOW";
size_t len = strlen(str); /* better to get actual length */
char lowers[len + 1]; /* add one for the nul char */
char uppers[len + 1]; /* (see below) */
int c;
int i = 0;
int n_upper = 0;
int n_lower = 0;
while ((c = str[i++]) != '\0') {
if (isupper(c)) uppers[n_upper++] = c; /* no need to reinvent */
if (islower(c)) lowers[n_lower++] = c; /* the wheel here */
}
uppers[n_upper] = '\0'; /* the nul char ('\0') marks */
lowers[n_lower] = '\0'; /* the end of a C "string" */
printf("1: %s\n", lowers);
printf("2: %s\n", uppers);
return 0;
}
Notes
If you are super concerned about efficiency you could add an else before if (islower...
Adding const means you "promise" the characters in the array won't be changed.
The type size_t is an integer type, but may be larger than int. It is the correct type for the return of strlen(). It is defined in <stdint.h>. None the less, using int will almost always work (on most systems a string would have to be 'yooooge' for its length to be bigger than an int can hold).
The variable c is declared as int instead of char because int is the proper type for the isXXXXX() functions (which are defined in <ctype.h>). It is also a good habit to get into because of the parallels between this loop and another common idiom while ((c = fgetc(fp)) != EOF) ....
You should consider using isupper() and islower() functions. Code would be cleaner. And what if you have some non alpha characters? Your conditions won't work.
for (i = 0; i < LEN; i++)
{
if (islower(str[i]))
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
else if (isupper(str[i]))
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
As #Ed Heal mention. To avoid printing rubbish, after for loopt you should add a null characters to arrays.
smallStr[indexSmall] = '\0';
bigStr[indexBig] = '\0';

How to remove the character at a given index from a string in C?

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));

Resources