Hey everyone,

I have to manipulate two functions RECURSIVELY, strlen and strcpy.

I was able to code the strlen:

int length(char* str){
	if(str == NULL){
		return 0;
	}else{
		return length(str, 0);
	}
}

int length(char* str, int l){
	int len=0;
	if(str[l]){
		len = length(str,l+1);
	} else {
		return l;
	}
	return len;
}

But I am having a lot of trouble with even beginning the strcpy function:

char copy(char* old_str, char* new_str){
	if(old_str == NULL){
		cout << "Could not copy, string is empty\n";
		return -1;
	}else{
		
	}
}

Here is my input on Strcpy:
- The base case can return -1 because you shouldn't have to copy nothing over to a new string.
- For the Recursive call, I have to go through the old_str recursively.

I appreciate all of the help.

Thank you.
-Ben

OK. I tried (and failed) to keep to the same code style as the one you had. (and cleaned up with some const correctness :) )
I came up with this (included main() to show how to use)

the RecursiveCopy function with no int argument checks to see if old_str is valid and if new_str is valid. it then calls the RecursiveCopy function with the int argument and it iterates through old_str and copies the data char by char into new_str

hope you like it :)

PS:
how do you feel about letting a 15 year old do your homework :) (if it is homework)

#include <windows.h>
#include <iostream>
using std::cout;


int length(const char* str, int l){
	int len=0;
	if(str[l]){
		len = length(str,l+1);
	} else {
		return l;
	}
	return len;
}

int length(const char* str){
	if(str == NULL){
		return 0;
	}else{
		return length(str, 0);
	}
}




void RecursiveCopy(const char* old_str, char* new_str, int iterator){
	if(old_str[iterator])	// stops at \0
	{
		new_str[iterator] = old_str[iterator];
		RecursiveCopy(old_str, new_str, iterator + 1);
	}
	else
	{
		new_str[iterator] = '\0';	// need to terminate the copied string
		return;
	}
}

// assumes new_str is allocated
bool RecursiveCopy(const char* old_str, char* new_str){
	if(old_str == NULL){
		cout << "Could not copy, string is empty\n";
		return false;
	}else if(length(new_str) < length(old_str)){
		cout << "Could not copy, destination is too small to fit the origional string into\n";
		return false;
	}else{
		RecursiveCopy(old_str, new_str, 0);
		return true;
	}
}

int main()
{
	char* test = "this is a test";	// length == 14 (+ 1 for the \0)
	char copy[15] = "0123456789ABCD";	// needs to be filled otherwise the validation may not work (by all means remove the validation if you want)

	RecursiveCopy(test, &copy[0]);

	cout<< "\""<< test<< "\"";
	cout<< "\n\n\n";
	cout<< "\""<< copy << "\"";

	return 0;
}

Edited 5 Years Ago by MattyRobot: n/a

>>how do you feel about letting a 15 year old do your homework (if it is homework)
I guess the OP should feel some shame in that. But, you should too (a bit). It is generally not helpful to the OP to simply post finished work.

@OP:
You should not need to pass an integer to do the recursion. Basically, you are using the integer to mark the current character that is being looked at. You can just as easily achieve this by moving the pointer (incrementing the pointer instead of calling with index + 1). I'll rewrite your length function to show how that can be done, you can then do the same for the copy function.

int length(const char* str){
  if(str && *str)                //or just: if(*str)  for more efficiency
    return 1 + length(++str);
  else
    return 0;
}

Edited 5 Years Ago by mike_2000_17: n/a

good point about the pointer. good point about me completing the whole thing (I got a bit carried away :)). in my defence about the extra parameter, I was copying what they had done for their length function, and its harder to overload without the extra parameter.

[EDIT]: oh wait, not aimed at me. but the bit about overloading still stands (but then i suppose you could use copy() and copy_step2(). my advice, dont use a recursive function where a loop would suffice :))

out of interest mike. how would you differentiate between the 'base' call to copy and the iterating call to copy

Edited 5 Years Ago by MattyRobot: n/a

>> my advice, dont use a recursive function where a loop would suffice

You wouldn't write these functions recursively in real life, but as a learning exercise for learning recursion, it's a good exercise. I'm wondering if there will be a follow-up exercise where the OP writes them recursively and non-recursively and then times them to see which is faster.

>>how would you differentiate between the 'base' call to copy and the iterating call to copy

Of course you can't use overloading for this purpose, but why would you? The point of overloading is not to have a helper function while not needing to come up with some alternative name. When you define a helper function, which is only meant to be called by the "real" function, then what you really want is to "hide" that helper function away from user-access (out of your interface). For that exact purpose (which comes up a lot) there are three wide-spread methods/conventions. The first, which is preferred if your function has its own translation unit (not a header-only library), is to use a mechanism built into C++, namely: unnamed namespaces. As so:

namespace {
  int length_recursive(const char* str){
    if(*str)
      return 1 + length_recursive(++str);
    else
      return 0;
  }
}

int length(const char* str) {
  if(str)
    return length_recursive(str);
  else
    return 0;
};

The second is to use a "detail" namespace. This is a convention to collect in one sub-namespace all the things you don't intend "outsiders" to use:

namespace detail {
  int length(const char* str){
    if(*str)
      return 1 + length(++str);
    else
      return 0;
  }
}

int length(const char* str) {
  if(str)
    return detail::length(str);
  else
    return 0;
};

Finally, if you are in C or namespaces are not usable for some reason, the good-old convention is to append the name _impl at the end. Most programmers, if they see _impl after a function or class name, they know that this is for the library developer's eyes only. As so:

int length_impl(const char* str){
  if(*str)
    return 1 + length_impl(++str);
  else
    return 0;
}

int length(const char* str) {
  if(str)
    return length_impl(str);
  else
    return 0;
};

And, of course, you wouldn't write these functions recursively in real-life code. You could write them recursively in a way that the end result is just the same as with a loop (probably my code above would) but why take the chance.

Edited 5 Years Ago by mike_2000_17: n/a

This question has already been answered. Start a new discussion instead.