I tried to write code using strrev(). I included <string.h> but still I'm getting an "undefined reference to strrev" error.
I found that strrev() doesn't have man page at all. Why?
Doesn't Linux support strrev()?
Correct. Use one of the alternative implementations available:
#include <string.h>
char *strrev(char *str)
{
char *p1, *p2;
if (! str || ! *str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
#include <string.h>
char *strrev(char *str)
{
if (!str || ! *str)
return str;
int i = strlen(str) - 1, j = 0;
char ch;
while (i > j)
{
ch = str[i];
str[i] = str[j];
str[j] = ch;
i--;
j++;
}
return str;
}
To accurately answer your question,
Is strrev() not available on Linux?
The functions strrev() available in the string.h library. Functions strrev() including some other string functions such as like strupr(), strlwr(), strrev(), which are only available in ANSI C (Turbo C/C++) and are not available in the standard C-GCC compiler.
It’s not about the system. It is about the C compiler you are using.
References:
https://discuss.codechef.com/t/is-strrev-function-not-available-in-standard-gcc-compiler/2449
https://www.csestack.org/undefined-reference-to-strrev/
Unfortunately, strrev seems to be absent from glibc's string.h.
Obviously, I'm late to the here's-some-code party, but I like this implementation.
#define MAX_CHARS 10000
// safe_usub -- perform safe unsigned subtraction
size_t safe_usub (size_t x, size_t y) {
return x > y ? x - y : y - x ;
}
char* str_reverse (const char* const str) {
if (!str) { return NULL; }
size_t len = strnlen(str, MAX_CHARS);
char* new = malloc( sizeof(char) * len );
size_t i;
for (i = 0; i < len; i++) {
new[i] = str[ safe_usub(i + 1, len) ];
}
new[i] = 0;
return new;
}
How about this:
#include <string.h>
char *strrev(char *s)
{
if (s && *s) {
char *b = s, *e = s + strlen(s) - 1;
while (b < e) {
char t = *b;
*b++ = *e;
*e-- = t;
}
}
return s;
}
There is no string library function to reverse a string.
strrev() Is not present in GCC compiler in Linux.
Make your own reverse function:
reverse.c:
/*
* C program to reverse a string using recursion
*/
#include <stdio.h>
#include <string.h>
void reverse(char [], int, int);
int main()
{
char str1[20];
int size;
printf("Enter a string to reverse: ");
scanf("%s", str1);
size = strlen(str1);
reverse(str1, 0, size - 1);
printf("The string after reversing is: %s\n", str1);
return 0;
}
void reverse(char str1[], int index, int size)
{
char temp;
temp = str1[index];
str1[index] = str1[size - index];
str1[size - index] = temp;
if (index == size / 2)
{
return;
}
reverse(str1, index + 1, size);
}
for exemple i need to invers "Paris" to "siraP"...
My main:
int main(void)
{
char w1[] = "Paris";
ReverseWord(w1);
printf("The new word is: %s",w1);
return0;
}
and my function:
void ReverseWord(char *Str)
{
int counter=0;
for(int i=0; *(Str+i)!='\0'; i++)
counter++;
int length = counter-1;
char temp[length];
for(int j=0; temp[j]=='\0'; j++)
temp[j]=Str[length-j];
}
Now I have my renverse word in temp[].
I need to put it in my pointer *Str.
How can I do it??
Thanks
If you want use temp must then your function like this
void ReverseWord(char *Str)
{
int i,j;
if(str)
{
int length=strlen(Str);
char temp[length+1];
for( j=0; j<length; j++)
temp[j]=Str[length-1-j];
temp[j]='\0';
strcpy(Str,temp);
}
}
Without using temp as follows
void ReverseWord(char *Str)
{
int end= strlen(Str)-1;
int start = 0;
while( start<end )
{
Str[start] ^= Str[end];
Str[end] ^= Str[start];
Str[start]^= Str[end];
++start;
--end;
}
}
void ReverseWord(char *Str)
{
size_t len;
char temp, *end;
len = strlen(Str);
if (len < 2)
return;
end = Str + len - 1;
while (end > Str)
{
temp = *end;
*end-- = *Str;
*Str++ = temp;
}
}
One more option, this time with dangerous malloc(3).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *rev(char s[]) {
char *buf = (char *)malloc(sizeof(char) * strlen(s));
int i, j;
if(buf != NULL)
for(i = 0, j = strlen(s) - 1; j >= 0; i++, j--)
buf[i] = s[j];
return buf;
}
int main(int argc, char **argv) {
printf("%s\n", rev(argv[1]));
return 0;
}
Run with "foo bar foobar baz" and get zab raboof rab oof back:
~/tmp$ ./a.out "foo bar foobar baz"
zab raboof rab oof
Here I think you can study two algorithms:
C string length calculate: the end of the c string is '\0'
How to reverse a c string in place
And if you need to test the code, you should alloc testing strings in heap or strack. If you write a literal string, you may meet a bus error because of the literal string being saved in text-area which is a read only memory.
And the following is the demo:
#include <stdio.h>
#include <stdlib.h>
void reverse_string(char* str)
{
size_t len;
char tmp, *s;
//Get the length of string, in C the last char of one string is \0
for(s=str;*s;++s) ;
len = s - str;
//Here we use the algorithm for reverse the char inplace.
//We only need a char tmp place for swap each char
s = str + len - 1;
while(s>str){
tmp = *s;
*s = *str;
*str = tmp;
s--;
str++;
}
}
int main()
{
char* a = "abcd";
//Here "abcd" will be saved in READ Only Memory. If you test code, you will get a bus error.
char* b = (char*)calloc(1,10);
strcpy(b,a);
reverse_string(b);
printf("%s\n",b);
a = "abcde";
strcpy(b,a);
reverse_string(b);
printf("%s\n",b);
}
you can do it simply by following code
for(int k=0;k<strlen(temp);k++)
{
Str[k]=temp[k];
}
I wanted to implement a reverse function for a null-terminated char* string (null-terminated char string, is that redundant?) and came up with the following solution.
The final swap swap(&tmp, &str) in the reverse function does not have any effect. What's the reason, how is it done probably?
Remark: I have already reimplemented the reverse function by using only the string itself, a temporary char and indices only, but I am so interested in why this does not work. What haven't I considered in this pointer matter?
#include <stdlib.h>
#include <stdio.h>
int strlen(char* str)
{
int len = 0;
char* ptr = str;
while (ptr[0] != '\0')
{
len++;
ptr++;
}
return len;
}
void swap(char **a, char **b)
{
char* c = *a;
*a = *b;
*b = c;
}
void reverse(char* str)
{
int len = strlen(str);
char* tmp = malloc(sizeof(char) * (len + 1));
int i;
for (i = 0; i < len; i++)
{
tmp[i] = str[len - 1 - i];
}
tmp[len] = '\0';
// printf(tmp); => "wolfrevOkcatS olleH"
swap(&tmp, &str);
}
int main(int argc, char** argv)
{
char* str = "Hello Stackoverflow\0";
reverse(str);
printf("%s", str);
return 0;
}
You can just do an in place reverse, and you won't need that pointer swap you're doing:
void reverse(char* str, int len)
{
int i;
for (i = 0; i < len; i++)
{
char tmp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = tmp;
}
}
To answer your question, you need to pass a char** to your reverse function, because you're changing what it will point to, and pointers are copied by value, so if you want to reflect the change of pointee you need a double pointer.
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));
I have just written a program which reverses a sentence whatever the user gives. For example: if the user enters "How are you", my program generates "uoy era woH".
The programme which I wrote is shown below. I just have a wild intution that there can be a smarter program than this. So valuable input from your side is most appreciated or any better program than this is also most welcome.
int ReverseString(char *);
main() {
char *Str;
printf("enter any string\n");
gets(Str);
ReverseString(Str);
getch();
}
int ReverseString(char *rev) {
int len = 0;
char p;
while(*rev!='\0') {
len++;
rev++;
}
rev--;
while(len>0) {
p = *rev;
putchar(p);
rev--;
len--;
}
}
Thanks a lot.
You could use recursion.
int ReverseString(char *rev) {
if(*rev!='\0') {
ReverseString(rev + 1);
putchar(*rev);
}
return 1;
}
void ReverseString( char* str, int len ) {
if( len > 1 ) {
swap( &str[0], &str[len - 1] );
ReverseString( ++str, len - 2 );
}
}
Or, unrolling the tail-recursion:
void ReverseString( char* str, int len ) {
while( len > 1 ) {
swap( &str[0], &str[len - 1] );
++str;
len -= 2;
}
}
Where swap is defined as:
void swap( char* a, char* b ) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
If you use this though, your TA's will definitely know you didn't figure this out yourself :)
Okay, here is my function. I wrote it a while ago, just for practice.
char* reverse(char *string){
int length = 0;
int half = 0;
length = strlen(string);
half = (length/2) - 1;
--length;
int i = 0;
register char interim;
for(; i<=half; ++i){
interim = string[i];
string[i] = string[length - i];
string[length - i] = interim;
}
return string;
}
now that I look at it, I'm less proud of it than when I got it to work. I'm just posting it because you asked me to post it when I found it--and for completeness' sake.
After looking at some other answers I realize that the calculation of half the string is unnecessary and I could have just decremented length until i and length were equal. Oh well--here it is.
Also, please don't bash me for the use of the register keyword :P
Yet another variation...
void ReverseString( char *str, int len ) {
int i;
for(i=0; i < len/2; i++) {
swap( &str[i], &str[len -1 -i] );
}
}
void swap( char *a, char *b ) {
char tmp = *a;
*a = *b;
*b = tmp;
}
void revstr(TCHAR *str) {
if( *str == '\0' ) {
return;
}
TCHAR *start = str;
TCHAR *end = start + strlen(str) - 1;
while(start < end) {
*start ^= *end;
*end ^= *start;
*start ^= *end;
*start++;
*end-–;
/*
could also use *start ^= *end ^= *start++ ^= *end–-; if you want to get fancy
*/
}
}
Stolen from the 2005 version of myself, but screw that guy, he slept with my wife. Yes, I know I don't need some of the '*'s, but I wrote the one-liner first and just converted it, and the one-liner does require them.
The following program prints its arguments in reverse character order:
#include <string.h>
#include <stdio.h>
char * reverse(char * string) {
char * a = string;
char * b = string + strlen(string) - 1;
for(; a < b; ++a, --b)
*a ^= *b, *b ^= *a, *a ^= *b; // swap *a <-> *b
return string;
}
int main(int argc, char * argv[]) {
for(int i = 1; i < argc; ++i)
puts(reverse(argv[i]));
}
Nothing new here, but IMO more readable than most other answers.
If you don't know the length of the string:
void reverse_string(char* str) {
char* p2 = str;
while (*p2 != '\0') {
/* assumes the string is null-terminated, will fail otherwise */
++p2;
}
--p2;
char* p1 = str;
while (p1 < p2) {
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
++p1;
--p2;
}
}
If you do:
void reverse_string(char* str, const size_t len) {
if (len <= 1) {
return;
}
char* p2 = str + len - 1;
char* p1 = str;
while (p1 < p2) {
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
++p1;
--p2;
}
}
This won't work. Should allocate memory for your sentence.
char *Str;
printf("enter any string\n");
gets(Str);
should be:
char str[81]={0};
printf("Enter any string up to 80 characters\n");
scanf("%80s\n",str);
ReverseString(str)
Besides, you should avoid gets function. It leads to buffer overflows
#include<stdio.h>
void reverse(char s[])
{
int i=0,j,x=0,z;
printf("\nThe string is : ");
printf("%s",s);
printf("\nThe reverse string is : ");
while(s[i] != ' ')
{
while(s[i] != ' ')
i++;
z=i+1;
for(j=i-1;j>=x;j--)
printf("%c",s[j]);
printf(" ");
i=z;
x=z;
}
}
main()
{
char s[50];
int a;
for(a=0;a<50;a++)
s[a]=' ';
puts("\nEnter a sentence : ");
fgets(s,50,stdin);
reverse(s);
}