I'm trying to reverse a string using recursion but it's not working.
What's the mistake?..
It's showing some output "tset a ♠♣♦♥☻☺" for test case "this is a test"
#include "stdio.h"
#include "string.h"
void rec(char [],int,int);
void main()
{
char ch[50];int j,i=0;
printf("Enter the string: ");
gets(ch);
j=strlen(ch)-1;
rec(ch,i,j);
puts(ch);
}
void rec(char ch[],int i,int j)
{
char t;
if(i>=j) return;
t=ch[i];
ch[i]=ch[j];
ch[j]=i;
rec(ch,++i,--j);
}
ch[j]=i;
You are assigning an integer to character which is not what you want.
You are storing the value in t so
ch[j] = t;
is what you need.
In this statement
ch[j]=i;
you are using i instead of t
The function could be written simpler with only two parameters. For example
void rec( char s[], size_t n )
{
if ( !( n < 2 ) )
{
char c = s[0];
s[0] = s[n-1];
s[n-1] = c;
rec( s + 1, n - 2 );
}
}
and called like
rec( ch, strlen( ch ) );
Now try to write the function with only one parameter: char s[]:)
You need to change
ch[j]=i;
to
ch[j]= t;
Note that no need to null terminate the string explicitly. strlen gives th length the string excluding the \0 character. You are passing strlen(ch)-1 to your function it means it will start reversing the characters from the character just before \0. So, after the reversal the string will be null terminated.
Related
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* findSequence(char s[], char ch, int n){
int i;
char*ptr;
char needle[n];
char*npdr=&needle;
for(i=0;i<n;i++){needle[i]=ch;}
ptr = strstr(s,ndpr);
printf("%s",ptr);
return ptr;
}
int main()
{
char stringa[]={"ciccciopasticcio"};
char carattere='c';
char*ptr;
int n=3;
ptr=findSequence(stringa, carattere,n);
return 0;
}
This quick code, should search for a matching between a string and a needle of non set lenght, it works just fine with any n>=3 the problem is with 1 and 2 as n values.
watching the debug i noticed that the pointer npdr adds a second and third value to the sequence on his own example: n=2 needle="cc" npdr=address of needle[0] "cc#"
Do you have any ideas of why this is happening?
The standard function strstr expects two pointers to strings. But you are calling the function passing an array as the second argument that does not contain a string - a sequence of characters terminated by the zero character '\0'
char needle[n];
char*npdr=&needle;
for(i=0;i<n;i++){needle[i]=ch;}
ptr = strstr(s,ndpr);
So the code invokes undefined behavior.
Also this initialization
char*npdr=&needle;
is incorrect. The initialized pointer has the type char * while the initializing expression has the type char ( * )[n]. At least you need to write
char*npdr=needle;
You could declare the array like
char needle[n + 1];
and
needle[n] = '\0';
Pay attention to that the function should not output any message. It is the caller of the function will decide whether to output a message. Moreover this call of printf
printf("%s",ptr);
will invoke undefined behavior if the pointer ptr is equal to NULL.
The function itself should be declared the following way
char* findSequence(const char s[], char ch, size_t n);
That is the first parameter should be declared with the qualifier const because passed strings are not changed within the function. And the second parameter should have unsigned integer type size_t instead of the signed integer type int.
Also using a variable length array within the function makes the function unsafe.
The function can be defined using standard C string function strchr instead of the function strstr.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
char * findSequence( const char s[], char ch, size_t n )
{
const char *p = NULL;
if (n != 0 && ch != '\0')
{
size_t count = 0;
do
{
count = 0;
p = strchr( s, ch );
if (p)
{
s = p;
do
{
++count;
} while (*++s == ch);
}
} while (p != NULL && count != n);
}
return ( char * )p;
}
int main( void )
{
char stringa[] = { "ciccciopasticcio" };
char carattere = 'c';
size_t n = 3;
char *ptr = findSequence( stringa, carattere, n );
if (ptr != NULL)
{
puts( ptr );
}
}
The program output is
ccciopasticcio
I have read the post here on the same subject, but it doesn't seem to have the solution to my problem.
If I need to write a function str_reverse() which reverses any string passed to it, how can I go about it? Just as the person who asked the question I linked above, the following code
#include <stdio.h>
#include <string.h> //for strlen
#define maxL 300 //Max String Length
void str_reverse(char);
int main(){
//Variables
char x[maxL];
//User Prompt
printf("Enter a string no longer than %d characters: ", maxL);
gets(x);
str_reverse(x);
//Return Statement
return 0;
}
void str_reverse(char x){
int i, l;
l = strlen(x);
printf("In reverse: ");
for(i=l-1; i>=0; i--)
printf("%c",x[i]);
}
gives me an error. How can I create a program which allows me to reverse the string?
You are passing fine but the function isn't receiving properly. Change it to:
void str_reverse(char *x){
..
}
and the prototype to:
void str_reverse(char*);
Also, gets() is dangerous and should never be used. Use fgets() instead:
if( fgets(x, sizeof x, stdin) == NULL) { /* failure */ }
x[strcspn(x,"\n")] = 0; // to remove the trailing newline, if any.
Your can pass array as type arr[] or as type * pointer. you will have to pass length as an argument to your string reverse function. New declaration of string reverse will look like this:
void str_reverse(char *x,int length)
or
void str_reverse(char x[],int length)
for more information you can follow Length of array in function argument
A function parameter declared as an array is adjusted to pointer to array element.
Thus these function declarations are equivalent and declare the same one function
#define maxL 300
void str_reverse(char[maxL]);
or
void str_reverse(char[10]);
or
void str_reverse(char[1000]);
or
void str_reverse(char[]);
or
void str_reverse( char *);
And on the other hand when an array is passed as an argument to a function it is implicitly converted to pointer to its first element.
So this function call
char x[maxL];
//...
str_reverse(x);
can be imagine like
char x[maxL];
//...
char *tmp = x;
str_reverse(tmp);
Take into account that function gets is unsafe and is not supported by the C Standard any more.
Use instead standard function fgets
Also it is better if the function returned pointer to its first character.
Your function does not try to reverse a string. It tries to output a string in the reverse order.
So the function that indeed reverses a string can be written like
char * str_reverse( char *s )
{
size_t n = strlen( s );
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;
}
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
#define maxL 300 //Max String Length
char * str_reverse( char *s )
{
size_t n = strlen( s );
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 )
{
//Variables
char s[maxL];
//User Prompt
printf("Enter a string no longer than %zu characters: ", maxL);
fgets( s, maxL, stdin );
s[strcspn( s, "\n" )] = '\0';
puts( str_reverse( s ) );
return 0;
}
Its output might look like
Enter a string no longer than 300 characters: Hello, World!
!dlroW ,olleH
You can achieve this by many different ways:
Option-1
Formal parameters as a pointer −
void myFunction(char *param) {
.
.
.
}
Option-2
Formal parameters as a sized array −
void myFunction(char param[10]) {
.
.
.
}
Option-3
Formal parameters as an unsized array −
void myFunction(char param[]) {
.
.
.
}
I want to write a recursive function in C languge that revers a word. I know how to do it with printing it, but actually reversing the original word I don't know how.
so, I want to write a function that revers a word, using pointers, using string.h, but has to be void, no printing, and changing the original word. the function prototype:
void reverse(char* string);
what I was able to write were the stop terms of the recursion(and i'm not sure if they are correct);
if(!string) return; // if the string is empty
if(*(string+1)=='\0' return (*string); // if there is only on char in the string
if(*(string+2))=='\0' // if there are only 2 letters In the strings-swap
temp=(*string);
(*string)= * (string+1);
(*string+1)= temp; // I don't know what to do after..
that would be great is go guys can explain to me what to do.
thank you.
An implementation with tail recursion:
#include <stdio.h>
#include <string.h>
/* function prototypes */
void reverse(char *string);
void reverseWorker(char *string, int start, int end);
int main(int argc, const char *argv[]) {
char string[] = "Hello, world.";
printf("string (original) = %s\n", string);
/*
reverse(string);
Or, to reverse each word in the string...
*/
char *ptr = strtok(string, " ");
while(ptr != NULL) {
reverse(ptr);
ptr = strtok(NULL, " ");
if(ptr != NULL)
*(ptr-1)=' ';
}
/* the rest is the same */
printf("string (reversed) = %s\n", string);
return 0;
}
void reverse(char *string) {
reverseWorker(string, 0, strlen(string)-1);
}
void reverseWorker(char *string, int start, int end) {
/* terminal condition */
if(start>=end)
return;
/* swap */
char temp = string[start];
string[start]=string[end];
string[end]=temp;
/* recursive step */
reverseWorker(string,start+1,end-1);
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void reversefill(char*const from,char*const to){
if(from>=to){
//Nothing to do. Odd lengths get to from==to.
//Even lengths 'swap over'.
//Pointer comparison guaranteed legit - in the same array.
return;
}
//Textbook swap.
//Could use the classic xor swap trick.
//However that will just confuse in this example.
const char temp=*from;
*from=*to;
*to=temp;
//Carry on moving our 'work' points closer together from both ends.
reversefill(from+1,to-1);
}
void reverse(char* str){
const size_t sz=strlen(str);
if(sz==0){
return;//Can't use str-1 - UB.
//Could head for the door if sz==1 but this is a training example on recursion.
//So we'll just show it works if from==to.
}
reversefill(str,str+sz-1);
}
int main() {
char*const str="Hello World!";
char*const rev=malloc(strlen(str)*sizeof(*str));//sizeof not required but good habit
strcpy(rev,str);
reverse(rev);
printf("%s\n",rev);
free(rev);//Don't listen to smart-arses who say that's unnecessary.
//Unless you really need to use the trick...
//However examples should be the cleanest possible code.
return EXIT_SUCCESS;
}
I think the requirement was in-place reversal.
The only way to do that (I think the OP realises) is to work from the ends and swap 'symmetric' positions. That is swap the first with last, second with second last, etc.
That's fine but we need to realise when we've 'met' in the middle.
That's obvious of odd length cases - the two working points meet.
For even cases we need to spot the workings 'crossing over'.
That's exactly how reversefill(,) works.
I think this code is an excellent specimen of the strengths and weaknesses of C strings.
The main function is fantastically efficient.
But actually has to scan the string twice because C doesn't intrinsically provide a O(1) way of obtaining the length of a string!
You could write the function like
void reverse( char s[] )
{
reverse_impl( s, strlen( s ) );
}
void reverse_impl( char s[], size_t n )
{
if ( !( n < 2 ) )
{
char c = s[0];
s[0] = s[n-1];
s[n-1] = c;
reverse_impl( s + 1, n - 2 );
}
}
But it is a wrong solution because it is not function void reverse( char s[] ); that is a recursive function. It is function void reverse_impl( char s[], size_t n ); that is recursive. But according to your assignment it is function void reverse( char s[] ); that has to be recursive.
So the correct solution is the following.
#include <stdio.h>
void reverse( char s[] )
{
if ( *s )
{
char *p = s;
char c;
do
{
c = *p;
*p = *( p + 1 );
*( p + 1 ) = c;
} while ( *p++ );
reverse( s );
c = *p;
*p = *( p - 1 );
*( p - 1 ) = c;
}
}
int main( void )
{
char s[] = "abcde";
puts( s );
reverse( s );
puts( s );
return 0;
}
The output is
abcde
edcba
This recursive function uses neither standard function :)
I am compressing string. And the compressed string sometimes having NULL character inside before the end NULL. I want to return the string till the end null.But the compressor function is returning the sting till the occurring of the first NULL. Please help me.
char* compressor(char* str)
{
char *compressed_string;
//After some calculation
compressed_string="bk`NULL`dk";// at the last here is automatic an NULL we all know
return compressed_string;
}
void main()
{
char* str;
str=compressor("Muhammad Ashikuzzaman");
printf("Compressed Value = %s",str);
}
The output is : Compressed Value = bk;
And all other characters from compressor function is not here. Is there any way to show all the string.
The function returns "entire string". It is printf that outputs it until the null character will be encountered.
You could define the function the following way
char * compressor( const char* source, size_t *result_len );
To understand the problem consider the following code
#include <stdio.h>
char * compressor( const char* source, size_t *result_len )
{
char *compressed_string = "bk\0dk";
*result_len = sizeof( "bk\0dk" );
return compressed_string;
}
int main( void )
{
char* str;
size_t n;
str = compressor( "Muhammad Ashikuzzaman", &n );
int i;
printf( "Compressed Value = " );
for ( char *p = str; n; n -= i + 1, p += i + 1 )
{
i = printf( "%s", p );
}
return 0;
}
The output is
Compressed Value = bkdk
#include <stdio.h>
#include <stdlib.h>
char* func(char *str, int *length)
{
int i;
*length=9;//Put string length you calculated
str=(char*)malloc(*length*sizeof(char));
for(i=0;i<5;i++)
str[i]=i+65;
str[5]=0;
str[6]=65;
str[7]=67;
str[8]=0;
return str;
}
int main()
{
char *str;
int i,length=0;
str=func("Muhammad Ashikuzzaman",&length);
for(i=0;i<length;i++)
printf("%c",str[i]);
scanf("%d",&i);
return 0;
}
Solution using std::string:
#include <string>
#include <iostream>
#include <iterator>
std::string compressor(char* str)
{
char *compressed_string;
int len; // this is the size of the compressed data
//...
// compress the data and assume that len has the number of characters
//...
std::string theString(compressed_string, len);
// clean up any memory here.
//...
return theString;
}
using namespace std;
int main()
{
std::string str = compressor("Muhammad Ashikuzzaman");
std::copy(str.begin(), str.end(), std::ostream_iterator<char>(cout,""));
}
Note the usage of std::string, as well as how the information is outputted using the copy algorithm function. The reason why copy is used instead of printf is to ensure that all of the characters, including the (invisible) embedded NULL's are printed.
Also, the size of the compressed data is easily retrieved by calling str::size().
I have the following code:
#include <stdio.h>
void insertion_sort(char[], int);
void swap(char*, char*);
int main() {
char s[] = "hello world";
puts(s);
insertion_sort(s, sizeof(s)/sizeof(char));
puts("done\n");
puts(s);
return 0;
}
void swap(char* a, char* b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
void insertion_sort(char s[], int n)
{
int i,j;
/* counters */
for (i=1; i<n; i++) {
j=i;
while ((j>0) && (s[j] < s[j-1])) {
swap(&s[j],&s[j-1]);
j = j-1;
}
printf("%s\n", s);
}
}
The problem is, after the insertion_sort() function call, s becomes empty - puts(s) prints nothing.
Please advise.
Change:
insertion_sort(s, sizeof(s)/sizeof(char));
to:
insertion_sort(s, strlen(s));
otherwise you will be including the '\0' terminator of s[] in your sort.
Note that you will need an additional header for strlen so change:
#include <stdio.h>
to:
#include <stdio.h> // printf etc
#include <string.h> // strlen etc
The problem is that the length that you pass to insertion_sort includes terminating \0 character, which happens to have value 0, so in sort it is placed as the first element of your array. This is why your last puts() prints nothing - because the first character is now "the end of a string".
I suggest you to calculate the size of a string using strlen() which will return the length of a string excluding terminating character. Or if you want to do it your way, take terminating character into consideration and substract it from the total length.