I am trying to reverse this C-string and I thought I did it correct but the string remains the same when it passes through the function.
#include <stdio.h>
char* reverse(char* string);
int main(int arc, char* argv[]) {
char word[] = "Hello World!";
printf("%s\n", word);
printf("%s\n", reverse(word));
return 0;
}
char* reverse(char* string) {
int i, j, n = 0;int len = 0;char temp;
//Gets string length
for (i = 0; *(string + i) != '0'; i++) {
len++;
}
//Reverses string
for (j = len - 1; j >= 0; j--) {
temp = string[n];
string[n] = string[j];
string[j] = temp;
n++;
}
return &string[0];
}
Expected output:
Hello World!
!dlroW olleH
For starters there is a typo
for (i = 0; *(string + i) != '0'; i++) {
You have to write
for (i = 0; *(string + i) != '\0'; i++) {
That is instead of the character '0' you have to use '\0' or 0.
In this for loop
for (j = len - 1; j >= 0; j--) {
temp = string[n];
string[n] = string[j];
string[j] = temp;
n++;
}
the string is reversed twice.:) As a result you get the same string.
The function can look for example the following way
char * reverse(char *string)
{
//Gets string length
size_t n = 0;
while ( string[n] != '\0' ) ++n;
//Reverses string
for ( size_t i = 0, m = n / 2; i < m; i++ )
{
char temp = string[i];
string[i] = string[n - i - 1];
string[n - i - 1] = temp;
}
return string;
}
Or the function can be defined the following way using pointers
char * reverse(char *string)
{
//Gets string length
char *right = string;
while ( *right ) ++right;
//Reverses string
if ( right != string )
{
for ( char *left = string; left < --right; ++left )
{
char temp = *left;
*left = *right;
*right = temp;
}
}
return string;
}
The same approach of the function implementation without using pointers can look the following way
char * reverse(char *string)
{
//Gets string length
size_t n = 0;
while ( string[n] != '\0' ) ++n;
//Reverses string
if ( n != 0 )
{
for ( size_t i = 0; i < --n; ++i )
{
char temp = string[i];
string[i] = string[n];
string[n] = temp;
}
}
return string;
}
Here is one more solution. I like it most of all. Tough it is inefficient but it is not trivial as the early presented solutions. It is based on an attempt of one beginner to write a function that reverses a string.:)
#include <stdio.h>
#include <string.h>
char *reverse( char *string )
{
size_t n = 0;
while (string[n]) ++n;
while (!( n < 2 ))
{
char c = string[0];
memmove( string, string + 1, --n );
string[n] = c;
}
return string;
}
int main( void )
{
char string[] = "Hello World!";
puts( string );
puts( reverse( string ) );
}
The program output is
Hello World!
!dlroW olleH
Of course instead of manually calculating the length of a string in all the presented solutions there could be used standard string function strlen declared in the header <string.h>.
The problem is that the input word[] is an array, which decays to a pointer when passed to the reverse function.
In the for loop, instead of using n to keep track of the position, I suggest you to use i and j to keep track of the start and end of the string, and increment and decrement them respectively and use strlen to get the length of string.
Also, as it is mentionned above by #Vlad from Moscow, in your for loop you are checking for 0 but it should be \0 which is the null character.
Please find down below an update of your posted code that is generating the expected result :
#include <stdio.h>
char* reverse(char* string);
int main(int arc, char* argv[]) {
char word[] = "Hello World!";
printf("%s ", word);
printf("%s\n", reverse(word));
return 0;
}
char* reverse(char* string) {
int i, j;
char temp;
int len = strlen(string);
//Reverses string
for (i = 0, j = len - 1; i < j; i++, j--) {
temp = string[i];
string[i] = string[j];
string[j] = temp;
}
return &string[0];
}
The output is as expected: Hello World! !dlroW olleH
Aditionnally, you can include the header <string.h> or explicitly
provide a declaration for 'strlen' to avoid the warning that indicate to implicitly declaring library function 'strlen' with type 'unsigned long (const char *)' [-Wimplicit-function-declaration]
I have a char array containing a number.
char number[] = "12000000"
I need to have a function to insert a divider in every 3 digits. Like:
char result[] = "12,000,000"
My function accepts the number as a char pointer and it needs to return result as a char pointer too.
char* insert_divider(char* number) {
some magic;
return result;
}
I have no idea of working with pointers. Thanks.
Here you have a function that adds char c every num characters starting from the end. You need to make sure that the string buffer is long enough to accommodate the amended string.
char *addEvery(char *str, char c, unsigned num)
{
char *end = str;
if(str && *str && num)
{
size_t count = 1;
while(*(end)) end++;
while(end != str)
{
end--;
count++;
if(!(count % (num + 1)) && str != end)
{
memmove(end + 1, end, count);
*end = c;
count++;
}
}
}
return str;
}
int main(void)
{
char str[100] = "120000000000";
printf("%s", addEvery(str,',',3));
}
I came up with this piece of code:
char *result;
result = (char*) malloc(15);
int len= strlen(input);
uint8_t cursor= 0;
for(int i = 0; i < len; i++) {
if ((len- i) > 0 && (len- i) % 3 == 0) {
result[i + cursor] = ',';
cursor++;
}
result[i + cursor] = input[i];
}
result[len+ cursor] = '\0';
Thanks everyone for help and advice.
Here is another way to do it:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* insert_divider(char* number, size_t length) {
int j = length + length/3; // every 3 digits a ',' will be inserted
char *out = (char*)malloc(j + 1);
out[j--] = '\0';
for (int i = length - 1, k = 1; i >= 0; i--, k++) {
out[j--] = number[i];
if ((k%3) == 0) {
out[j--] = ',';
}
}
return out;
}
int main(){
char number[] = "12000000";
char *outNumber = insert_divider(number, strlen(number));
printf("%s", outNumber);
free(outNumber);
return 0;
}
What I need to write:
1.Get a main string from user.
2.Get a subString from a user.
Every match of the subString in the main string, change its letters to uppercase.
Do not use string's functions like strstr.
For example:
main string: abcdeffghfhkfff
sub string: ff
outut: abcdeFFghfhkFFf
Problem: Well, I'm having troubles to continue writing the code after I found one match. for example after I found the first 'f' in the main string, how can I continue check if the second 'f' is adjacent to the found 'f', if not, then try to find another 'f' and check subsequent matches of the subarray until we've found that the length of the substring matches the number of subsequent matches in the string? Here's what I've tried, and in writing the logic of the for loop in 'replaceSubstring' function
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include <string.h>
#define N 101
void replaceSubstring(char *str, char *subStr);
void main()
{
char str[N], subStr[N];
while (strlen(str) != 0 || strlen(subStr) != 0)
{
str[0] = 0;
printf("Enter text: ");
gets(str);
printf("Enter substring: ");
scanf("%s", subStr);
replaceSubstring(str, subStr);
}
}
void replaceSubstring(char *str, char *SubStr)
{
int i, count = 0, j = 0, k = 0;
for (i = 0; i <= strlen(str); i++)
{
if (str[i] == SubStr[k])
{
k++;
count++;
if (count == strlen(SubStr))
{
str[i] -= 32;
}
}
}
puts(str);
getchar();
}
You can use strstr() function to do this more easly, like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 101
void replaceSubstring(char *str, char *subStr);
void main()
{
char str[N], subStr[N];
while (strlen(str) != 0 || strlen(subStr) != 0)
{
str[0] = 0;
printf("Enter text: ");
gets(str);
printf("Enter substring: ");
scanf("%s", subStr);
replaceSubstring(str, subStr);
}
}
void replaceSubstring(char *str, char *SubStr)
{
int i;
char *tmp;
while((tmp = strstr(str, SubStr)) != NULL)
{
for (i = 0; i < strlen(SubStr); i++)
{
tmp[i] -= 32;
}
}
puts(str);
getchar();
}
Here another version of replaceSubstring() function without using strstr() function:
void replaceSubstring(char *str, char *SubStr)
{
int i = 0, found = 1, j = 0, k = 0;
while (i < strlen(str))
{
if (str[i] == SubStr[0])
{
found = 1;
for(k = 0; k < strlen(SubStr); k++)
{
if(str[i+k] != SubStr[k])
{
found = 0;
break;
}
}
if(found)
{
for(k = 0; k < strlen(SubStr); k++)
{
str[i+k] -= 32;
}
i += strlen(SubStr);
}
else
i++;
}
else
i++;
}
puts(str);
getchar();
}
To solve this without using strstr(), i would do something like this:
void replaceSubstring(char *str, char *SubStr)
{
int i = 0, equals = 0, j = 0, k = 0;
for(i=0;i<strlen(str);i++){
j = i;
equals = 1;
k=0;
while(k<strlen(SubStr)&&(equals == 1)){
if(SubStr[k] != str[j]){
equals = 0;
}
k++;
j++;
}
if(equals == 1){
for(j=i;j<i+k;j++){
str[j] -= 32;
}
}
}
puts(str);
getchar();
}
I'm pretty sure this works correctly.
input: abcdeffghfhkfff
substring: ff
output: abcdeFFghfhkFFf
Here is a demonstrative program that shows how the function can be written
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * replaceSubstring( char *s1, const char *s2 )
{
char *p = s1;
size_t n = strlen( s2 );
while ( ( p = strstr( p, s2 ) ) != NULL )
{
for ( size_t i = 0; i < n; ++i, ++p ) *p = toupper( ( unsigned char )*p );
}
return s1;
}
int main( void )
{
char s[] = "abcdeffghfhkfff";
puts( s );
puts( replaceSubstring( s, "ff" ) );
}
Its output is
abcdeffghfhkfff
abcdeFFghfhkFFf
Take into account that according to the C Standard function main without parameters shall be declared like`
int main( void )
Also it is a bad idea to use "magic" numbers like 32 like in this statement
tmp[i] -= 32;
For example if in the environment there are used EBCDIC characters then this statement will be simply wrong.
Moreover even for ASCII characters this statement is invalid because it is not necessary that original characters are in lower case.
This is a very small question, and probably something really silly! But why am I getting garbage returned in my output for this function which should remove double letters?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char *makehello( char *s ) {
char new[16] ;
int i ;
int c = strlen(s);
for ( i = 0; i < (c + 1); i++)
if (toupper(s[i]) != toupper(s[i+1]))
new[i] = toupper(s[i]);
return strdup( new ) ;
}
int main(void) {
char *new;
char data[100];
scanf("%s", data);
new = makehello(data);
printf("%s", new);
return 0;
}
You need a separate count for your 'new' array. You're storing them at index 'i' (where you found the character), but what you really want is to store them from position 0 and increment this count instead.
EDIT: Of course this isn't a fullproof method.
i.e something like this:
for ( i = 0; i < c; i++)
{
if (toupper(s[i]) != toupper(s[i+1]))
{
new[count++]= toupper(s[i]);
}
}
new[count] = '\0';
The line
for ( i = 0; i < (c + 1); i++)
should be
for ( i = 0; i < (c - 1); i++)
And you then need before the strdup new[i]=0;
Braces would not go amise either.
EDIT
Forgot need to change the following
int i, j=0;
and in the for loop
new[j++] = toupper(s[i]);
and after the for loop
new[j] = 0;
Here's a reasonably compact C99 version of the algorithm (headers omitted, example):
const char * makehello (const char * s)
{
char new[16] = { *s, 0 };
const char * p = s;
char c = *s, * q = new;
while (*p) { if (*++p != c) { c = *++q = *p; } }
return strdup(new) ;
}
int main(void)
{
char data[100];
scanf("%s", data);
printf("%s", makehello(data));
return 0;
}
(This one discriminates case.)
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));