以下实现了C++标准模板库中std::string中的部分实现,参考了cplusplus.
关于C++中标准模板库std::string的介绍和用法可以参考: https://blog.csdn.net/fengbingchun/article/details/62417284
实现代码string.hpp如下:
#ifndef FBC_STL_STRING_HPP_
#define FBC_STL_STRING_HPP_
#include
namespace fbcstd {
class string {
public:
string();
string(const string& str);
string(const string& str, size_t pos, size_t len = npos);
string(const char* s);
string(const char* s, size_t n);
string(size_t n, char c);
~string();
const char* c_str() const;
size_t length() const;
size_t size() const;
char& operator [] (size_t pos);
const char& operator [] (size_t pos) const;
string& operator = (const string& str);
string& operator = (const char* s);
string& operator = (char c);
string& operator += (const string& str);
string& operator += (const char* s);
string& operator += (char c);
string& append(const string& str);
string& append(const char* s);
string& assign(const string& str);
string& assign(const char* s);
char& at(size_t pos);
const char& at(size_t pos) const;
void clear();
int compare(const string& str) const;
int compare(const char* s) const;
const char* data() const;
bool empty() const;
static const size_t npos = -1;
private:
size_t size_;
char* buffer_;
}; // class string
inline string::string()
{
size_ = 0;
buffer_ = new char[1];
buffer_[0] = '\0';
}
inline string::string(const string& str)
{
size_ = str.size_;
buffer_ = new char[size_+1];
strcpy(buffer_, str.buffer_);
}
inline string::string(const string& str, size_t pos, size_t len)
{
if (pos > str.size_) {
size_ = 0;
buffer_ = new char[1];
buffer_[0] = '\0';
} else {
if (pos + len > str.size_)
size_ = str.size_ - pos;
else
size_ = len;
buffer_ = new char[size_+1];
const char* p = str.c_str() + pos;
for (size_t i = 0; i < size_; ++i) {
buffer_[i] = p[i];
}
buffer_[size_] = '\0';
}
}
inline string::string(const char* s)
{
size_ = strlen(s);
buffer_ = new char[size_+1];
strcpy(buffer_, s);
}
inline string::string(const char* s, size_t n)
{
if (strlen(s) <= n) {
size_ = strlen(s);
buffer_ = new char[size_+1];
strcpy(buffer_, s);
} else {
size_ = n;
buffer_ = new char[size_+1];
strncpy(buffer_, s, n);
}
}
inline string::string(size_t n, char c)
{
size_ = n;
buffer_ = new char[size_+1];
memset(buffer_, c, n);
}
inline string::~string()
{
if (buffer_)
delete [] buffer_;
size_ = 0;
}
inline const char* string::c_str() const
{
return buffer_;
}
inline size_t string::length() const
{
return size_;
}
inline size_t string::size() const
{
return size_;
}
inline char& string::operator [] (size_t pos)
{
return buffer_[pos];
}
inline const char& string::operator [] (size_t pos) const
{
if (pos >= size_)
return '\0';
else
return buffer_[pos];
}
inline string& string::operator = (const string& str)
{
if (this->size_ != 0)
delete [] buffer_;
size_ = str.size_;
buffer_ = new char[size_+1];
strcpy(buffer_, str.c_str());
return *this;
}
inline string& string::operator = (const char* s)
{
if (this->size_ != 0)
delete [] buffer_;
size_ = strlen(s);
buffer_ = new char[size_+1];
strcpy(buffer_, s);
return *this;
}
inline string& string::operator = (char c)
{
if (this->size_ != 1)
delete [] buffer_;
size_ = 1;
buffer_ = new char[size_+1];
buffer_[0] = c;
buffer_[size_] = '\0';
return *this;
}
inline string& string::operator += (const string& str)
{
size_ += str.size_;
char* data = new char[size_+1];
strcpy(data, buffer_);
strcat(data, str.buffer_);
delete [] buffer_;
buffer_ = data;
return *this;
}
inline string& string::operator += (const char* s)
{
size_ += strlen(s);
char* data = new char[size_+1];
strcpy(data, buffer_);
strcat(data, s);
delete [] buffer_;
buffer_ = data;
return *this;
}
inline string& string::operator += (char c)
{
size_ += 1;
char* data = new char[size_+1];
strcpy(data, buffer_);
strcat(data, &c);
delete [] buffer_;
buffer_ = data;
return *this;
}
inline string& string::append(const string& str)
{
*this += str;
return *this;
}
inline string& string::append(const char* s)
{
*this += s;
return *this;
}
inline string& string::assign(const string& str)
{
*this = str;
return *this;
}
inline string& string::assign(const char* s)
{
*this = s;
return *this;
}
inline char& string::at(size_t pos)
{
return buffer_[pos];
}
inline const char& string::at(size_t pos) const
{
return buffer_[pos];
}
inline void string::clear()
{
delete [] buffer_;
size_ = 0;
buffer_ = new char[1];
buffer_[0] = '\0';
}
inline int string::compare(const string& str) const
{
return strcmp(buffer_, str.buffer_);
}
inline int string::compare(const char* s) const
{
return strcmp(buffer_, s);
}
inline const char* string::data() const
{
return buffer_;
}
inline bool string::empty() const
{
return (size_ == 0);
}
static inline string operator + (const string& lhs, const string& rhs)
{
string str(lhs);
str += rhs;
return str;
}
static inline string operator + (const string& lhs, const char* rhs)
{
string str(lhs);
str += rhs;
return str;
}
static inline string operator + (const char* lhs, const string& rhs)
{
string str(lhs);
str += rhs;
return str;
}
static inline string operator + (const string& lhs, char rhs)
{
string str(lhs);
str += rhs;
return str;
}
static inline string operator + (char lhs, const string& rhs)
{
string str(&lhs);
str += rhs;
return str;
}
static inline bool operator == (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) == 0);
}
static inline bool operator == (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) == 0);
}
static inline bool operator == (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) == 0);
}
static inline bool operator != (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) != 0);
}
static inline bool operator != (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) != 0);
}
static inline bool operator != (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) != 0);
}
static inline bool operator < (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) < 0);
}
static inline bool operator < (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) >= 0);
}
static inline bool operator < (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) < 0);
}
static inline bool operator <= (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) <= 0);
}
static inline bool operator <= (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) > 0);
}
static inline bool operator <= (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) <= 0);
}
static inline bool operator > (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) > 0);
}
static inline bool operator > (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) <= 0);
}
static inline bool operator > (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) > 0);
}
static inline bool operator >= (const string& lhs, const string& rhs)
{
return (lhs.compare(rhs) >= 0);
}
static inline bool operator >= (const char* lhs, const string& rhs)
{
return (rhs.compare(lhs) < 0);
}
static inline bool operator >= (const string& lhs, const char* rhs)
{
return (lhs.compare(rhs) >= 0);
}
} // namespace fbcstd
#endif // FBC_STL_STRING_HPP_
测试代码test_string.cpp如下:
#include
#include "string.hpp"
#define std fbcstd
int main()
{
{ // constructor
std::string s0("Initial string");
fprintf(stdout, "s0: %s\n", s0.c_str());
std::string s1;
fprintf(stdout, "s1: %s\n", s1.c_str());
std::string s2(s0);
fprintf(stdout, "s2: %s\n", s2.c_str());
std::string s3(s0, 8, 3);
fprintf(stdout, "s3: %s\n", s3.c_str());
std::string s4("A character sequence ");
fprintf(stdout, "s4: %s\n", s4.c_str());
std::string s5("Another character sequence", 12);
fprintf(stdout, "s5: %s\n", s5.c_str());
std::string s6a(10, 'x');
fprintf(stdout, "s6a: %s\n", s6a.c_str());
std::string s6b(10, 42);
fprintf(stdout, "s6b: %s\n", s6b.c_str());
} // constructor
{ // length, size, c_str()
std::string str("Test string");
fprintf(stdout, "str length: %d\n", str.length());
fprintf(stdout, "str size: %d\n", str.size());
fprintf(stdout, "str: %s\n", str.c_str());
}
{ // operator []
std::string str("Test String");
const char &c1 = str[0], &c2 = str[5];
fprintf(stdout, "c1: %c; c2: %c; str: %s\n", c1, c2, str.c_str());
char &c3 = str[0], &c4 = str[5];
c3 = 't'; c4 = 's';
fprintf(stdout, "c3: %c; c4: %c; str: %s\n", c3, c4, str.c_str());
}
{ // operator =
std::string str("https://blog.csdn.net/fengbingchun/");
std::string str1, str2, str3;
str1 = str;
str2 = "https://github.com/fengbingchun";
str3 = 'x';
fprintf(stdout, "str1: %s; str2: %s; str3: %s\n", str1.c_str(), str2.c_str(), str3.c_str());
}
{ // operator +=
std::string name("John");
std::string family("Smith");
name += " K. ";
name += family;
name += '\n';
fprintf(stdout, "name: %s", name.c_str());
}
{ // append
std::string str1 = "CSDN: ";
std::string str2 = "https://blog.csdn.net/fengbingchun/";
str1.append(str2);
fprintf(stdout, "str1: %s\n", str1.c_str());
std::string str3("GitHub: ");
str3.append("https://github.com/fengbingchun");
fprintf(stdout, "str3: %s\n", str3.c_str());
}
{ // assign
std::string str1, str2;
std::string str3("CSDN: https://blog.csdn.net/fengbingchun/");
str1.assign(str3);
fprintf(stdout, "str1: %s\n", str1.c_str());
str2.assign("GitHub: https://github.com/fengbingchun");
fprintf(stdout, "str2: %s\n", str2.c_str());
}
{ // at
std::string str("Test String");
const char& a = str.at(5);
fprintf(stdout, "a: %c, str: %s\n", a, str.c_str());
char& b = str.at(5);
b = 's';
fprintf(stdout, "b: %c, str: %s\n", b, str.c_str());
}
{ // clear
std::string str("Test String");
fprintf(stdout, "str: %s\n", str.c_str());
str.clear();
fprintf(stdout, "str: %s\n", str.c_str());
}
{ // compare
std::string str1("Test"), str2("String"), str3("Apple"), str4("String");
fprintf(stdout, "str2:str1: %d; st2:str3: %d; str2:str4: %d\n",
str2.compare(str1), str2.compare(str3), str2.compare(str4));
fprintf(stdout, "str2:str1: %d; st2:str3: %d; str2:str4: %d\n",
str2.compare("Test"), str2.compare("Apple"), str2.compare("String"));
}
{ // data, empty
std::string str("Test String"), str2;
fprintf(stdout, "str: %s\n", str.data());
fprintf(stdout, "str is empty: %d; st2 is empty: %d\n", str.empty(), str2.empty());
}
{ // operator +
std::string firstlevel("com");
std::string secondlevel("cplusplus");
std::string scheme("http://");
std::string hostname;
std::string url;
hostname = "www." + secondlevel + '.' + firstlevel;
url = scheme + hostname;
fprintf(stdout, "url: %s\n", url.c_str());
}
{ // operator: ==, !=, <, <=, >, >=
std::string foo = "alpha";
std::string bar = "beta";
if (foo == bar) fprintf(stdout, "foo == bar\n");
if (foo != bar) fprintf(stdout, "foo != bar\n");
if (foo < bar) fprintf(stdout, "foo < bar\n");
if (foo > bar) fprintf(stdout, "foo > bar\n");
if (foo <= bar) fprintf(stdout, "foo <= bar\n");
if (foo >= bar) fprintf(stdout, "foo >= bar\n");
}
return 0;
}
CMakeLists.txt内容如下:
PROJECT(Samples_STL_Implementation)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2 -std=c++11")
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src)
MESSAGE(STATUS "project source dir: ${PROJECT_SOURCE_DIR}")
FILE(GLOB tests ${PROJECT_SOURCE_DIR}/test/*.cpp)
FOREACH (test ${tests})
STRING(REGEX MATCH "[^/]+$" test_file ${test})
STRING(REPLACE ".cpp" "" test_basename ${test_file})
ADD_EXECUTABLE(${test_basename} ${test})
TARGET_LINK_LIBRARIES(${test_basename} pthread)
ENDFOREACH()
脚本build.sh内容如下:
#! /bin/bash
real_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"
new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
cmake ..
make
cd -
编译及测试方法:将终端定位到Samples_STL_Implementation目录下,执行:$ ./build.sh , 然后再执行$ ./build/test_string即可。
GitHub: https://github.com/fengbingchun/Linux_Code_Test