I am currently studying C and I can't get past this exercise. I must create a recursive function to reverse string1 into string2. Here is my code. I would gladly appreciate your help.
#include <stdio.h>
#define MAX 100
void reverse(char s1[],char s2[],int n,int j);
int main()
{
char string1[MAX]="How Are You Mate";
char string2[MAX]="";
int n=0;
int i=0;
int j=0;
for(i=0;string1[i]!='\0';i++)
n++;
reverse(string1,string2,n,j);
printf("String-a normal:\n%s\n",string1);
printf("String-a reverse:\n%s\n",string2);
return 0;
}
void reverse(char s1[],char s2[],int n,int j)
{
if(n>0)
{
s2[j]=s1[n];
reverse(s1,s2,n-1,j+1);
}
else
s2[j]='\0';
}
in-place (the caller could make a copy of the string before calling this function) string reverse with tail-recursion
void reverse (char *str, size_t len)
{
char tmp;
if (len-- < 2) return;
tmp = *str;
*str = str[len];
str[len] = tmp;
reverse (str+1, len -1);
}
O, if you don't want pointers:
void reverse (char str[], size_t len)
{
char tmp;
if (len-- < 2) return;
tmp = str[0];
str[0] = str[len];
str[len] = tmp;
reverse (str+1, len -1);
}
The reversing starts by copying the n-th character of string1 array into string2. The n-th character happens to be the null terminator. It becomes the first character of your new string, so the string looks empty to all standard C routines, including printf.
Calling
reverse(string1,string2,n-1,j);
from the main should fix the problem. The condition in the reverse should be changed from if(n>0) to if(n>=0) as well.
Although it does not save the resulting string anywhere, you get the idea.
#include <stdio.h>
void rev (const char* str);
int main () {
const char str[] = "!dlrow ,olleH";
printf("%s\n", str);
rev(str);
printf("\n");
return 0;
}
void rev (const char* str) {
char c = *str;
if (c != '\0') {
rev(str + 1);
printf("%c", c);
}
}
I have corrected the program. Please find the changes below
void reverse(char s1[],char s2[],int n,int j)
{
if(n>0)
{
s2[j]=s1[n-1];
reverse(s1,s2,--n,++j);
}
else
s2[j]='\0';
}
i recommend using library , size=strlen(array) in stead of
for(i=0;string1[i]!='\0';i++)
n++;
to count how many characters in arra
Related
If the line "n=str_len(s);" is commented, n is printed, else it just compiles, but when run, nothing happens. Need help understanding what is missing here. Thanks.
// C Program to get string length
#include<stdio.h>
//int str_len(char *s);
int str_len(char *s){
printf("in function");
char *c =s;
while(c!='\0')
c++;
return c-s;
}
int main(){
char *s="Hello World";
int n=0;
//printf("n = %d",n);
//printf("String :%s\n",*s);
n = str_len(s);
//printf("String :%s",*s);
printf("Length :%d\n",n);
}
Not comparing what c points to.
// while(c!='\0')
while(*c != '\0')
Wrong type. Use size_t. int maybe insufficient. All array sizes, and so string lengths, fit in size_t.
// int str_len(char *s){
size_t str_len(char *s){
strlen() works with const char *
All together
size_t str_len(const char *s) {
// printf("in function");
const char *c = s;
while(*c) {
c++;
}
return (size_t) (c - s);
}
Ref size_t strlen(const char *s); C11 §7.23.6.3 1
I have created a function for strend, which basically returns 1 if string t is present at the end of string s, however it never returns 1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int strend(char *s, char *t) {
int p;
for (p = 0; p < strlen(s) - strlen(t); p++) {
*s++;
}
printf("%s\n%s\n", s, t);
if (s == t)
return 1;
return 0;
}
int main(void) {
int bool = strend("Hello", "ello");
printf("%i\n", bool);
return 0;
}
This gives me an output of:
ello
ello
0
So technically I should get 1. I assume the comparison using pointers is not used in this way?
You need to review your basic knowledge of C strings. There are lots of standard string functions in string.h that can help you with this test.
The basic problem is that the test s == t is valid, but you are comparing memory addresses here. You can see that is valid if you change the strings to test to
char test[] = "Hello";
int bool = strend_(test, test+1);
where test obviously is the same as your "Hello", and similarly, test+1 is the same as "ello" (try it by printing them). This correctly returns 1 with your routine.
In addition, I get two warnings:
on *s++; "warning: expression result unused [-Wunused-value]": you increment s but also ask what character is at that position through *s; and you don't use that information.
Fix by removing the * there.
on p < strlen(s) ..; "warning: comparison of integers of different signs: 'int' and 'unsigned long'", because strlen does not return a signed integer but an unsigned one (apparently, my header uses unsigned long).
Fix by declaring p as unsigned long, or even better, size_t.
Your entire routine can be condensed to a simple
int strend (char *s, char *t)
{
if (strlen(s) >= strlen(t) && !strcmp (s+strlen(s)-strlen(t),t))
return 1;
return 0;
}
It's not worth the trouble to cache the result of those four strlen calls into 2 temporary variables; a good compiler will work it out and do that for you. (A quick glance to the assembly output of the compiler I'm using – clang – shows it does, even with the default optimization settings.)
A slightly modified test, based on #M.M.'s comment:
int strend (char *s, char *t)
{
if (strlen(s) < strlen(t)) return 0;
return !strcmp (s+strlen(s)-strlen(t),t);
}
but attempting to optimize it this way is not as easy parsed as the routine above, and its assembly is ever so slightly "wordy" as well. Personally, I'd go for the more humanly readable version.
Use strcmp(3)
if (strcmp(s, t) == 0) return 1;
This actually compares the contents of the memory pointed to by s and t rather than their addresses.
Your code is broken in multiple ways:
The initial loop is a very cumbersome way to advance p by the difference of lengths if positive.
Once you have pointers at the same distance from the end of both strings, You should compare the characters with strcmp() (or memcmp() if you can first exclude the case of strlen(s) < strlen(t).
Comparing the pointers obtained after the loop will only work if t points inside the string pointed to by s, a special case that may or may not be produced by the compiler for the specific call in main: strend("Hello", "ello");.
Here is a modified version:
#include <string.h>
int strend(const char *str1, const char *str2) {
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
return len1 >= len2 && !memcmp(str1 + len1 - len2, str2, len2);
}
I corrected/modified your code, here is the code,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#pragma warning(disable:4996)
int strend(char *s, char *t)
{
int p,flag=0,count=0;//count will be the starting index for *t
p = strlen(s) - strlen(t);//this will be the starting index for *s
while(count<strlen(t))
{
if (*(s+p) == *(t+count))
{
flag = 1;
count++;
p++;
continue;
}
else
{
flag = 0;
break;
}
}
return flag;
}
int main(void)
{
int flag = strend("Hello", "ello");
printf("%i\n", flag);
return 0;
}
This code works too.
#include <stdio.h>
#include <string.h>
int strend (char *s1, char *s2);
void main ()
{
char str1[20] = "somethings";
char str2[20] = "things";
int f;
f = strend (str1,str2);
if (f==1)
printf ("1");
else
printf ("0");
}
int strend (char *str1, char *str2)
{
int l = strlen(str1) - strlen(str2);
str1 = str1 + l;
int d = strcmp(str1,str2);
if (d == 0)
return 1;
else
return 0;
}
this code works well.
int strend(char *s, char *t){
while(*t & *s){
if(*t == *s){
t++;
}
s++;
}
return *t==*s;
}
i'm trying to reverse a string using recursion and a single pointer to that string.
My idea is to traverse the string from both edges, raising the pointer and inserting '\0's at the end of the string. For example - given a string 'abcde\0' - replace "chars" before the middle of the string, and insert '\0' after -> recursive calls -> when "stop condition" is reached, original string should be like this - 'edc\0\0\0' - and half of chars stored as temp variable, in stack. When turning back and popping the stack, these chars should overwrite the '\0' in reverse order. This is the idea.
This is my code so far, but I can't get it work - please help me understand, what do I miss. I have a '\0' in the middle of string that I can't figure out how to rewrite it. (I guess this is the major problem)
Thanks in advance.
#include <stdio.h>
#include <string.h>
void rev_str(char* _str);
int main()
{
char str[]="abcde";
puts("Str before:");
puts(str);
rev_str(str);
puts("Str after");
puts(str);
return 0;
}
void rev_str(char* _str)
{
int len=strlen(_str);
char temp=*_str;
if(len>1)
{
*_str = _str[len-1];
_str[len-1]='\0';
rev_str(++_str);
}
_str[len-1]=temp;
}
I won't debug your code, however this might help you understand things better -
http://www.programmingsimplified.com/c-program-reverse-string
Examples taken from page -
C program to reverse a string using pointers
Now we will invert string using pointers or without using library function strrev.
#include<stdio.h>
int string_length(char*);
void reverse(char*);
main()
{
char string[100];
printf("Enter a string\n");
gets(string);
reverse(string);
printf("Reverse of entered string is \"%s\".\n", string);
return 0;
}
void reverse(char *string)
{
int length, c;
char *begin, *end, temp;
length = string_length(string);
begin = string;
end = string;
for (c = 0; c < length - 1; c++)
end++;
for (c = 0; c < length/2; c++)
{
temp = *end;
*end = *begin;
*begin = temp;
begin++;
end--;
}
}
int string_length(char *pointer)
{
int c = 0;
while( *(pointer + c) != '\0' )
c++;
return c;
}
C program to reverse a string using recursion
#include <stdio.h>
#include <string.h>
void reverse(char*, int, int);
int main()
{
char a[100];
gets(a);
reverse(a, 0, strlen(a)-1);
printf("%s\n",a);
return 0;
}
void reverse(char *x, int begin, int end)
{
char c;
if (begin >= end)
return;
c = *(x+begin);
*(x+begin) = *(x+end);
*(x+end) = c;
reverse(x, ++begin, --end);
}
rev_str(++_str);
This is the problem. You're modifying _str here so when you do _str[len-1]=temp at the end, you're writing to the wrong location. Change it to
rev_str(_str + 1);
Just change the code rev_str(++_str); into rev_str(_str+1);. The ++_str equal to _str += 1, it will change the pointer char *_str. But _str+1 will only initialize the formal param, and will not change the 'char *str'. I hope this can help you.
I am attempting to complete a homework assignment, part of which is to design a function that inserts a string into another string. All functions, with the exception of strlen(), are off limits to me. Specifically the problem is this: I am having trouble implementing the part of the function that "makes room" in the target string for the inserted string. Inserting the string always results in a trampling of array elements. Can anyone point out what I am doing wrong here? Thanks for helping me learn!
Edit: Integer n is the location in the string that I am supposed to insert the other string.
void insertstring(char *str, char *ins, int n)
{
int i;
int scoot=strlen(ins);
char *p=str+n;
for (i=strlen(str); i > n; --i) { //This is where I'm doing it wrong I think
str[i+scoot]=str[i]; //
}
do {
*p = *ins;
++p;
++ins;
}
while (*ins != '\0');
}
An elegant solution uses reversing to achieve the desired result. Assume your target string, str, is composed of two blocks, AB, where A is the block before the insertion point, and B is the block after insertion point. Furthermore, assume that the string to insert, ins, is denoted by a third block C.
It can be seen that if you concatenate C to AB and then reverse B, reverse C, and reverse both B and C, you get ACB, which is the desired result. More explicitly, this is what you have after appending C to AB:
ABC
And this is what you want:
ACB
ACB can be obtained by:
Reverse B, to get B_r (B reversed);
Reverse C, to get C_r - at this point we have AB_rC_r;
Reverse both B and C, that is, compute A(B_rC_r)_r, which yields ACB.
Here's the code that implements this algorithm:
void reverse(char *, char *, char *);
/* Insert string C between blocks AB in str */
void insertstring(char *str, char *ins, int n) {
/* 1 - Append C to the end of str */
int i = strlen(str);
char *p = str+i, *q = ins;
while ((*p++ = *q++));
p--;
/* 2 - Reverse C and B */
reverse(str, str+i, p-1); /* C */
reverse(str, str+n, str+i-1); /* B */
/* 3 - Reverse B_rC_r */
reverse(str, str+n, p-1);
}
void reverse(char *str, char *begin, char *end) {
char tmp;
while (begin < end) {
tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
}
And some sample code to test it:
#include <stdio.h>
#include <string.h>
int main() {
void insertstring(char *, char *, int);
char test[128] = "A string to test.";
printf("Before: %s\n", test);
insertstring(test, "hello!", 4);
printf("After: %s\n", test);
return 0;
}
This will insert "hello!" beginning in test[4]. Here's the output:
$ ./test
Before: A string to test.
After: A sthello!ring to test.
Consider taking this approach: the code is short and elegant. This technique is described in Programming Pearls, 2nd edition, as a good way to perform vector rotation. According to the author, Brian Kernighan and P.J. Plauger used precisely this method in their Software Tools in Pascal to move lines within a text editor.
First you have change
for (i=strlen(str); i > n; --i)
to
for (i=strlen(str); i >= n; --i)
because you have to move str[n] too.
The other problem is when you insert ins:
do {
*p = *ins;
++p;
++ins;
}
while (*ins != '\0');
Here you copy the terminating '\0' from ins to str so the rest is lost. Change it to
while (*ins != '\0') {
*p = *ins;
++p;
++ins;
}
After mentioning about n, update for loop as
for (i=n+scoot; i >= n; i--)
You want to move strlen(ins) number of character ahead from location n.
Tried it with single loop,
go to index , copy src content into temp_array and simultaneously copying medi into src
once medi is copied completely , start putting the content of temp_array till it become empty
void insert_in_middle (char *src, char *medi, int index)
{
int i=0, j = index, k=0;
char temp_array[50];
while(src[j] != '\0' || temp_array[k] != '\0')
{
temp_array[i] = src[j];
if(medi[i] != '\0')
{
src[j] = medi[i];
}
else if(temp_array[k] != '\0')
{
src[j] = temp_array[k];
k++;
}
i++; j++;
}
printf("src[%s]\n", src);
printf("medi[%s]\n",medi);
printf("temp_array[%s]\n",temp_array);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *str_ins();
int main()
{
char *test = "Hello, world!";
printf("%s\n",test);
str_ins(&test,strstr(test,"world"),"my ");
printf("%s\n",test);
}
char *str_ins(a, b, c) // insert string c into a at point b
char **a, *b, *c;
{
char *stemp;
int pos = strlen(*a) - strlen(b);
stemp = (char *) malloc(strlen(*a)+strlen(c)+1);
strncpy(stemp,*a,pos);
strcpy(stemp+pos,c);
strcat(stemp,b);
free(a);
*a = stemp;
return *a;
}
I have come across this question in a programming contest, but couldn't find the answer can anyone please help me with this???
Input<<string
Output<<reverse(string)
constraints: No loops allowed,No inbuilt functions have to be used!
Use recursion:
#include <stdio.h>
void print_reversed(const char* str) {
if (*str) {
print_reversed(str + 1);
printf("%c", *str);
}
}
int main() {
print_reversed("abcdef");
printf("\n");
}
To give a concrete answer based on NPE's hint to use recursion, we need to use recursion for two things: finding the end of the string, and actually swapping everything.
Here is a complete program illustrating this approach (see it run):
#include <stdio.h>
char * find_end_of_string(char *str)
{
return *str ? find_end_of_string(str + 1) : str;
}
void do_reverse_string(char *a, char *b)
{
char tmp;
if (a < b) {
tmp = *a;
*a = *b;
*b = tmp;
do_reverse_string(a + 1, b - 1);
}
}
void reverse_string(char *str)
{
do_reverse_string(str, find_end_of_string(str) - 1);
}
int main() {
char odd[] = "abcde";
char even[] = "abcdef";
reverse_string(odd);
reverse_string(even);
printf("%s\n%s\n", odd, even);
return 0;
}