My length function with class

I showed my some code to you, and I have to use my_len function for length.

How can I do it for my_len(?????) . What should I write as a function parameter? Should I create Constructor? What is your advice for "??????" point ?

Thanks a lot.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class String
{
public:

	String();

	bool empty();        

	String(char * other_str);

	bool equals(const String other_str);
	
	int length();
	

private:
char* m_str;

	
};



------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "String.hpp"
#include <string>
#include<iostream>


int my_len(const char* p) {
	int c = 0;
	while (*p != '\0')
	{
		c++;
		p++;
	}
	return c;
}

//COPY FUNCTION
void my_cpy(char* dest, const char* src) {

	int i = 0;
	while (src[i] != '\0') {
		dest[i] = src[i];
		i++;
	}
	dest[i] = '\0';
}

//MY STRDUP FUNCTION
char *my_strdup(const char *s) {
	char* d = (char*)malloc((my_len(s) + 1) * sizeof(char));
	if (d == NULL) {
		return NULL;
	}
	else {
		my_cpy(d, s);
	}
	return d;

}

String::String()
	:m_str(NULL)
{
}

String::String(char * other_str)
{
	m_str = (other_str ? my_strdup(other_str) : other_str);
}



int String::length() 
{
	return my_len(m_str);
}


bool String::empty()
{
	return true;
}


bool String::equals(const String other_str)
{
	if (m_str == NULL && other_str.m_str == NULL) {
		return true;
	}

	if (m_str == NULL && other_str.m_str != NULL) {
		return false;
	}

	if (m_str != NULL && other_str.m_str == NULL) {
		return false;
	}

	if (m_str != NULL && other_str.m_str != NULL) {

		int mystrlen = my_len(m_str);
		int myrhslen = my_len(other_str.m_str);

		if (mystrlen != myrhslen)
		{
			return false;
		}
		else
		{
			for (int i = 0; i < mystrlen; i++)
			{
				if (m_str[i] != other_str.m_str[i])
				{
					return false;
				}
				else {
					return true;
				}
			}
			
		}
	}
}


------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "String.hpp"
#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <stdlib.h>

#define TEST_TRUE(x) printf("Test '%s' %s\n", #x, (x) ? "passed" : "failed!")

int main()
{
	// Test default constructor.
    String empty_string;									
    TEST_TRUE(empty_string.empty());

    String empty_string2(NULL);
    TEST_TRUE(empty_string2.empty());

	String empty_string3("");
    TEST_TRUE(empty_string3.empty());

	// Test the assignment operator.
    String empty_string4 = "";
    TEST_TRUE(empty_string4.empty());


    TEST_TRUE(empty_string.equals(empty_string2));
    TEST_TRUE(empty_string2.equals(empty_string3));
    TEST_TRUE(empty_string3.equals(empty_string4));


	int i;
	char name[10];
	strcpy(name, "Bob");

	char* str = malloc(10);
	free(str);

    char const* hello_world_str = "Hello World";
    String string1 = hello_world_str;
    TEST_TRUE(string1.length() == 11);
}
Last edited on
How will class String be storing its contents? Presumably there will be at least one member variable, you could have several, for example an area to hold the actual characters of the string. You might also have an integer for the current length, and maybe some other variables which you might decide would be useful.

Depending on what choices you make or have already made, the rest of the code will follow.
You haven't shown enough of your class declaration to answer your question.
Okey I showed. I have to do something for length() . What is your advice?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class String
{
public:

	String();

	bool empty();        

	String(char * other_str);

	bool equals(const String other_str);
	
	int length();
	

private:
char* m_str;

	
};



------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "String.hpp"
#include <string>
#include<iostream>


int my_len(const char* p) {
	int c = 0;
	while (*p != '\0')
	{
		c++;
		p++;
	}
	return c;
}

//COPY FUNCTION
void my_cpy(char* dest, const char* src) {

	int i = 0;
	while (src[i] != '\0') {
		dest[i] = src[i];
		i++;
	}
	dest[i] = '\0';
}

//MY STRDUP FUNCTION
char *my_strdup(const char *s) {
	char* d = (char*)malloc((my_len(s) + 1) * sizeof(char));
	if (d == NULL) {
		return NULL;
	}
	else {
		my_cpy(d, s);
	}
	return d;

}

String::String()
	:m_str(NULL)
{
}

String::String(char * other_str)
{
	m_str = (other_str ? my_strdup(other_str) : other_str);
}



int String::length() 
{
	my_len(........???.........);
}


bool String::empty()
{
	return true;
}


bool String::equals(const String other_str)
{
	if (m_str == NULL && other_str.m_str == NULL) {
		return true;
	}

	if (m_str == NULL && other_str.m_str != NULL) {
		return false;
	}

	if (m_str != NULL && other_str.m_str == NULL) {
		return false;
	}

	if (m_str != NULL && other_str.m_str != NULL) {

		int mystrlen = my_len(m_str);
		int myrhslen = my_len(other_str.m_str);

		if (mystrlen != myrhslen)
		{
			return false;
		}
		else
		{
			for (int i = 0; i < mystrlen; i++)
			{
				if (m_str[i] != other_str.m_str[i])
				{
					return false;
				}
				else {
					return true;
				}
			}
			
		}
	}
}


------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "String.hpp"
#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <stdlib.h>

#define TEST_TRUE(x) printf("Test '%s' %s\n", #x, (x) ? "passed" : "failed!")

int main()
{
	// Test default constructor.
    String empty_string;									
    TEST_TRUE(empty_string.empty());

    String empty_string2(NULL);
    TEST_TRUE(empty_string2.empty());

	String empty_string3("");
    TEST_TRUE(empty_string3.empty());

	// Test the assignment operator.
    String empty_string4 = "";
    TEST_TRUE(empty_string4.empty());


    TEST_TRUE(empty_string.equals(empty_string2));
    TEST_TRUE(empty_string2.equals(empty_string3));
    TEST_TRUE(empty_string3.equals(empty_string4));


	int i;
	char name[10];
	strcpy(name, "Bob");

	char* str = malloc(10);
	free(str);

    char const* hello_world_str = "Hello World";
    String string1 = hello_world_str;
    TEST_TRUE(string1.length() == 11);
}
Last edited on
String.h
--------
Lines 7, 11, 13: These functions should be const. They do not modify the class.

Line 14: You do not have a destructor for your class. You're using dynamically allocated memory. You need to free the memory you allocated, or you will have a memory leak.

String.cpp
----------
Line 2: Why are you including the std::string header? You don't use the std::string class.

Line 6: Your my_len function looks reasonable.

Line 54: Why is this so hard?
 
  return my_len(m_str);


Line 60: Obviously this isn't going to give the correct answer if the string is not empty.

Line 96: return true is in the wrong place. You're going to return true on the first character that matches. You don't want to return true until all the characters have been matched.





my_len would be faster if you incremented only one variable to find the end of the string and then used pointer arithmetic to compute the length. Something like:
1
2
3
4
const char *p_end;
for (p_end = p; *p_end; ++p_end)
    ;
return p_end - p;

Or you could just let the compiler do the optimization on something like this, which is clearer code, at least to my eyes:
1
2
3
4
size_t i;
for (i=0; p[i]; ++i)
    ;
return i;
@AbstractionAnon Do you think about bool function , why? Can you write to me? In addition, what is your advice about position of return true?
@dhayden Thanks a lot. Now i am focus on TEST_TRUE(string1.length() == 11);

Also i edited question , I added my all codes.

Now, I wrote

1
2
3
4
int String::length() 
{
	return my_len(m_str);
}


But I have to 2 errors.


1
2
3
Error	C2440	'initializing': cannot convert from 'void *' to 'char *'	       Line 56	

Error	C2440	'initializing': cannot convert from 'const char *' to 'String'	Line	60	


How can i solve this problem?
Last edited on
@AbstractionAnon Do you think about bool function , why?

I don't understand your question. If you're asking if empty() should be a bool function, then yes. A String is either empty (true) or it's not (false). So a bool function makes perfect sense.
1
2
3
bool String::empty () const
{  return m_str ? my_len(m_str) == 0 : true;  // m_str could be NULL
}


what is your advice about position of return true?

I already answered that. The return true should go AFTER you have matched all the characters as being equal. i.e. put the return true at line 99.

Regarding your 2 errors, the line numbers (56,60) do not match up to the code you posted.
Line 56 is a blank line and line 60 is a return statement. Please provide line numbers that match up to the code you posted.

Edit:
Okay, I tried to compile your program. The errors I received were in main.cpp, not string.cpp.
(35): error C2440: 'initializing': cannot convert from 'void *' to 'char *'

malloc returns a void *. You have to cast that to the type of left side of the assignment;
 
  char* str = (char *)malloc(10);

Although I don't see the point of lines 35-36. They accomplish nothing.

(39): error C2440: 'initializing': cannot convert from 'const char *' to 'String'

You have a constructor that takes a char *, but not a const char *. The compiler can not convert a const char * to a char *.
Last edited on
@AbstractionAnon

Thanks a a lot. Now I have just this error:
error C2440: 'initializing': cannot convert from 'const char *' to 'String'

How can I solve this problem? Can you write for me?

When I change the constructor in header and cpp String(char * other_str); to String(const char * other_str);

but now problem on:

m_str = (other_str ? my_strdup(other_str) : other_str);

Error:

Error (active) a value of type "const char *" cannot be assigned to an entity of type "char *"


Error C2440 '=': cannot convert from 'const char *' to 'char *'


What is your advice?


Thank you very much.
Last edited on
Um... isn't this thread just a duplicate of:

http://www.cplusplus.com/forum/general/205885/

Please don't start multiple threads for the same question. It wastes everyone's time.
closed account (SECMoG1T)
to add on something for safety precautions

1
2
3
4
5
6
7
8
9
void my_cpy(char* dest, const char* src) {

	int i = 0;
	while (src[i] != '\0') {
		dest[i] = src[i];
		i++;
	}
	dest[i] = '\0';
}


that function needs bound checking or you will get a buffer overflow.// just a security caution
Topic archived. No new replies allowed.