String.cpp
#include "String.h"
int String::strlen(const char *s) {
int len = 0;
for (; s[len] != END; ++len);
return len;
}
int String::num_allocations = 0; // note must be initialized to be a definition, static gone
char *String::strcpy(char *dest, const char *src) {
int i;
for (i = 0; src[i] != END; ++i)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
char *String::strcat(char *dest, const char *src) {
strcpy(dest + strlen(dest), src);
return dest;
}
char* String::strdup(const char* src) {
int len = strlen(src);
char* dup = new_char_array(len + 1);
int i = 0;
for (i; i < len; i++) {
dup[i] = src[i];
}
dup[i] = '\0';
return dup;
}
int String::strcmp(const char *left, const char *right) {
while(*left && (*left==*right)){
++left;
++right;
}
return *left - *right;
}
int String::strncmp(const char *left, const char *right, int n) {
if (n <= 0)
return 0;
while (--n && (*left) != END && (*right) != END && *left == *right)
{
left++;
right++;
}
return (*left - *right);
}
char *String::strchr(char *str, int c) {
for (int i = 0; str[i] != '\0'; ++i) {
if (str[i] == c)
return str + i;
}
return nullptr;
}
const char *String::strstr(const char *haystack, const char *needle) {
return strstr((char*)haystack, needle);
}
char *String::strstr(char *haystack, const char *needle) {
char *cp = (char *) haystack;
char *s1, *s2;
if (!*needle)
return ((char *) haystack);
while (*cp) {
s1 = cp;
s2 = (char *) needle;
while (*s1 && *s2 && !(*s1 - *s2))
s1++, s2++;
if (!*s2)
return (cp);
cp++;
}
return nullptr;
}
void String::reverse_cpy(char *dest, const char *src) {
int len = strlen(src);
for (int i = len - 1; i >= 0; --i)
dest[len - i - 1] = src[i];
dest[len] = END;
}
String::String(const char *s) {
int len = strlen(s);
buf = new_char_array(len+1);
strcpy(buf, s);
}
String::String(const String &s) {
int len = strlen(s.buf);//s的长度
buf = new_char_array(len+1);
strcpy(buf, s.buf);
}
char &String::operator[](int index) {
if (index < size())
return buf[index];
else {
cerr << "index " << index << " out of size[" << strlen(buf) << "]" << endl;
return buf[0];
}
}
String String::operator=(const String &s) {
strcpy(buf, s.buf);
return *this;
}
int String::size() {
return strlen(buf);
}
String String::reverse() {
String t(buf);
reverse_cpy(t.buf, buf);
return t;
}
String::~String() {
delete_char_array(buf);
}
bool String::operator==(const String &s) const {
return strcmp(buf, s.buf) == 0;
}
bool String::operator!=(const String &s) const {
return strcmp(buf, s.buf) != 0;
}
bool String::operator>(const String &s) const {
return strcmp(buf, s.buf) > 0;
}
bool String::operator<(const String &s) const {
return strcmp(buf, s.buf) < 0;
}
bool String::operator<=(const String &s) const {
return strcmp(buf, s.buf) <= 0;
}
bool String::operator>=(const String &s) const {
return strcmp(buf, s.buf) >= 0;
}
String String::operator+(const String &s) {
int len = this->size() + strlen(s.buf);
char* tmp_new = new_char_array(len + 1);
int i = 0;
for (; this->buf[i] != END; i++) {
tmp_new[i] = this->buf[i];
}
int j = 0;
for (; s.buf[j] != END; j++) {
tmp_new[i+j] = s.buf[j];
}
tmp_new[i+j] = END;
String t(tmp_new);
delete_char_array(tmp_new);
return t;
}
String String::operator+=(const String &s) {
int len = this->size() + strlen(s.buf);
char* tmp_new = new_char_array(len + 1);
int i = 0;
for (; this->buf[i] != END; i++) {
tmp_new[i] = this->buf[i];
}
int j = 0;
for (; s.buf[j] != END; j++) {
tmp_new[i + j] = s.buf[j];
}
tmp_new[i + j] = END;
delete_char_array(buf);
buf = tmp_new;
return *this;
}
void String::read(istream &in) {
char tmp[MAXLEN];
in.getline(tmp, MAXLEN);
buf = new_char_array(strlen(tmp)+1);
strcpy(buf, tmp);
}
void String::print(ostream &out) {
out << buf;
}
int String::indexOf(const char &c) const {
char *ret = strchr(this->buf, c);
if (ret != nullptr)
return (int) (ret - buf);
else
return -1;
}
int String::indexOf(const String &pattern) const {
char *ret = strstr(this->buf, pattern.buf);
if (ret != nullptr)
return (int) (ret - buf);
else
return -1;
}
char* String::new_char_array(int n_bytes) {
num_allocations++;
return new char[n_bytes];
}
void String::delete_char_array(char* p) {
num_allocations--;
delete[] p;
}
ostream &operator << (ostream &out, String str) {
str.print(out);
return out;
}
istream &operator >> (istream &in, String &str) {
str.read(in);
return in;
}
String.hpp
#ifndef STRING_H
#define STRING_H
#define MAXLEN 128
#include
using namespace std;
class String
{
public:
/// Both constructors should construct this String from the parameter s
explicit String(const char *s = "");
String(const String &s);
String operator=(const String &s);
char &operator[] (int index);
int size();
String reverse(); // does not modify this String
int indexOf(const char &c) const;
int indexOf(const String &pattern) const;
bool operator==(const String &s) const;
bool operator!=(const String &s) const;
bool operator>(const String &s) const;
bool operator<(const String &s) const;
bool operator<=(const String &s) const;
bool operator>=(const String &s) const;
/// concatenates this and s to return result
String operator+(const String &s);
/// concatenates s onto end of this string
String operator+=(const String &s);
void print(ostream &out);
void read(istream &in);
~String();
private:
const static char END = '\0';
bool inBounds(int i) {
return i >= 0 && i < strlen(buf);
} // HINT: some C string primitives you should define and use
static int strlen(const char *s);
static int num_allocations; // new declaration
static char *strcpy(char *dest, const char *src);
static char *strcat(char *dest, const char *src);
static char* strdup(const char* src);
static int strcmp(const char *left, const char *right);
static int strncmp(const char *left, const char *right, int n);
static char *strchr(char *str, int c);
/* haystack "The quick brown fox ran up the lazy log"
needle "ran" */
static const char *strstr(const char *haystack, const char *needle);
static char *strstr(char *haystack, const char *needle);
static void reverse_cpy(char *dest, const char *src);
static char* new_char_array(int n_bytes);
void delete_char_array(char* p);
char *buf; // array for the characters in this string
// DO NOT store the 'logical' length of this string
// use the null '\0' terminator to mark the end
};
ostream& operator << (ostream& out, String str);
istream& operator >> (istream& in, String& str);
#endif
#include "String.h"
//#include "String.cpp"
int main()
{
String firstString("First");
String secondString("Second");
String thirdString(firstString);
String fourthString("Fourth");
String fifthString = String();
std::cout << "+: " << firstString + secondString << std::endl;
std::cout << "+=: " << (firstString += secondString) << std::endl;
std::cout << "indexOf(String): " << firstString.indexOf(secondString) << std::endl;
std::cout << "indexOf(char): " << firstString.indexOf('t') << std::endl;
std::cout << "LT: " << (secondString < firstString) << std::endl;
std::cout << "GT: " << (secondString > firstString) << std::endl;
std::cout << "LE: " << (secondString <= firstString) << std::endl;
std::cout << "GE: " << (secondString >= firstString) << std::endl;
std::cout << "<<: " << fifthString << std::endl;
std::cout << "<<: " << fourthString << std::endl;
std::cout << "==: " << (fifthString == fourthString) << std::endl;
std::cout << "indexOf(String): " << fourthString.indexOf(fifthString) << std::endl;
std::cout << "size(): " << fifthString.size() << std::endl;
std::cout << "size(): " << fourthString.size() << std::endl;
std::cout << "[]: " << thirdString[1] << std::endl;
std::cout << "reverse(): " << fourthString.reverse() << std::endl;
fifthString = thirdString;
std::cout << "<<: " << fifthString << " " << thirdString << std::endl;
std::cout << "[]: " << fifthString[1] << std::endl;
std::cout << "[]: " << fifthString[10] << std::endl;
std::cout << "!=: " << (fifthString != thirdString) << std::endl;
std::cout << "Enter a test string: ";
std::cin >> firstString;
std::cout << firstString << std::endl;
std::cout << (firstString < secondString) << std::endl;
std::cout << (firstString <= thirdString) << std::endl;
std::cout << (firstString > fourthString) << std::endl;
std::cout << (firstString >= fifthString) << std::endl;
return 0;
}