C++ string的认识

在C++编程中,std::string类是一个非常重要的组成部分,用于处理和操作字符串。

1. string基础知识

std::string是C++标准库中的一个模板类,用于表示和操作字符串。它提供了丰富的成员函数和运算符重载,方便我们进行字符串的创建、修改、比较等操作。

1.1 字符串的创建

  • 默认构造函数:创建一个空字符串。
  • 带初始值的构造函数:可以直接用C风格的字符串字面量初始化。
  • 拷贝构造函数:通过另一个std::string对象来初始化。

1.2 字符串的访问

  • 使用下标运算符[]at()成员函数访问指定位置的字符。
  • 使用front()back()成员函数分别访问第一个和最后一个字符。

1.3 字符串的修改

  • 使用append()push_back()等成员函数添加字符或字符串。
  • 使用erase()pop_back()等成员函数删除字符或字符串。
  • 使用replace()成员函数替换字符串中的部分子串。

1.4 字符串的比较

  • 使用==!=<<=>>=等运算符比较两个字符串。
  • 使用compare()成员函数进行更复杂的比较操作。

2. string常用操作

2.1 字符串的连接

使用+运算符或append()成员函数连接两个字符串。

2.2 字符串的查找

  • 使用find()成员函数查找子串在字符串中的位置。
  • 使用rfind()成员函数从后向前查找子串在字符串中的位置。
  • 使用find_first_of()find_last_of()成员函数查找第一个或最后一个匹配字符的位置。

2.3 字符串的分割

C++标准库没有直接提供字符串分割的函数,但可以通过find()substr()成员函数结合使用来实现。

2.4 字符串的转换

  • 使用c_str()成员函数将std::string转换为C风格的字符串。
  • 使用to_string()函数(在<string>头文件中)将其他类型(如整数、浮点数)转换为std::string
#include <iostream>  
#include <string>  
#include <sstream>  
  
int main() {  
    // 使用c_str()将std::string转换为C风格的字符串  
    std::string str = "Hello, World!";  
    const char* cstr = str.c_str();  
    std::cout << "C-style string: " << cstr << std::endl;  
  
    // 使用to_string将整数转换为std::string(注意:to_string在<string>头文件中定义)  
    int num = 123;  
    std::string strNum = std::to_string(num);  
    std::cout << "String from integer: " << strNum << std::endl;  
  
    // 使用ostringstream进行更复杂的格式化和转换  
    std::ostringstream oss;  
    oss << "Number: " << num << ", String: " << str;  
    std::string formattedStr = oss.str();  
    std::cout << "Formatted string: " << formattedStr << std::endl;  
  
    return 0;  
}

3. string高级用法

3.1 字符串的迭代

使用迭代器遍历字符串中的每个字符。

#include <iostream>  
#include <string>  
  
int main() {  
    std::string str = "Hello";  
  
    for (std::string::iterator it = str.begin(); it != str.end(); ++it) {  
        std::cout << *it;  
    }  
    std::cout << std::endl;  
  
    // 使用C++11的范围for循环  
    for (char ch : str) {  
        std::cout << ch;  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

3.2 字符串的格式化

结合C++20中的std::format(或之前的std::ostringstream)来进行字符串的格式化输出。

3.3 字符串的性能优化

  • 了解std::string的内存管理机制,避免不必要的拷贝操作。
  • 使用std::string_view(C++17引入)来避免字符串拷贝,提高性能。

总和一些基础知识,这里提供一个模拟实现的版本

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;

namespace kuto
{
	class MyString
	{
	public:
		//迭代器
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}

		//构造函数
		MyString(const char* str = "")
			:_size(strlen(str))
		{
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		//析构函数
		~MyString()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}
		//拷贝构造函数s1(s2)
		MyString(const MyString& s)
		{
			//不存在的对象
			/*_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;*/

			MyString tmp(s._str);
			swap(tmp);
		}
		//s1 = s2赋值重载
		MyString& operator=(const MyString& s)
		{
			//已经存在的对象
			/*char* tmp = new char[s._capacity + 1];
			strcpy(tmp, s._str);
			delete[] _str;
			_str = tmp;
			_size = s._size;
			_capacity = s._capacity;
			return *this;*/

			MyString tmp(s);
			swap(tmp);
			return *this;
		}

		//模拟string返回size和capacity
		size_t size() const
		{
			//不修改成员函数
			return _size;
		}
		size_t capacity() const
		{
			return _capacity;
		}

		const char* c_str() const
		{
			return _str;
		}
		//重载[]
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}

		//替换扩容实现
		void resize(size_t n, char ch = '\0')
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				reserve(n);
				for (size_t i = _size; i < n; i++)
				{
					_str[i] = ch;
				}
				_str[n] = '\0';
				_size = n;
			}
		}
		//扩容
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}
		//插入push_back和append
		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
		}
		void append(const char* str)
		{
			size_t len = strlen(str);
			if (len + _size > _capacity)
			{
				reserve(len + _size);
			}
			strcpy(_str + _size, str);
			_size += len;
		}

		//运算符重载
		MyString& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		MyString& operator+=(const char* str)
		{
			append(str);
			return *this;
		}

		//模拟实现insert
		void insert(size_t pos, char ch)
		{
			assert(pos <= _size);
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			size_t end = _size + 1;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_size++;
		}
		void insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			int end = _size + len;
			while (end > pos + len -1)
			{
				_str[end] = _str[end - len];
				end--;
			}
			strncpy(_str + pos, str, len);
			_size = _size + len;
		}
		//模拟实现erase
		void erase(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos ||  len > _size - pos)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
		}
		//swap函数的实现
		void swap(MyString& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		//find函数的实现
		size_t find(char ch, size_t pos = 0) const
		{
			assert(pos < _size);
			for (size_t i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
				{
					return i;
				}
			}
			return npos;
		}
		size_t find(const char* ch, size_t pos = 0) const
		{
			assert(pos < _size);
			char* n = strstr(_str, ch);
			if (n != NULL)
			{
				return n - _str;
			}
			else
			{
				return npos;
			}
		}
		//substr实现
		MyString substr(size_t pos = 0, size_t len = npos)
		{
			MyString ret;
			if (len > _size - pos)
			{
				for (size_t i = pos; i < _size; i++)
				{
					ret += _str[i];
				}
			}
			else
			{
				for (size_t i = pos; i < pos + len; i++)
				{
					ret += _str[i];
				}
			}
			return ret;
		}
		void clear()
		{
			_size = 0;
			_str[_size] = '\0';
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		const static int npos;
	};

	const int MyString::npos = -1;
	void swap(MyString& x, MyString& y)
	{
		x.swap(y);
	}
	//重载==\<\<=\>\>=\!=
	bool operator==(const MyString s1,const MyString& s2)
	{
		int ret = strcmp(s1.c_str(), s2.c_str());
		return ret == 0;
	}
	bool operator>(const MyString s1, const MyString& s2)
	{
		int ret = strcmp(s1.c_str(), s2.c_str());
		return ret > 0;
	}
	bool operator>=(const MyString s1, const MyString& s2)
	{
		return s1 > s2 || s1 == s2;
	}
	bool operator<(const MyString s1, const MyString& s2)
	{
		return !(s1 >= s2);
	}
	bool operator<=(const MyString s1, const MyString& s2)
	{
		return s1 < s2 || s1 == s2;
	}
	bool operator!=(const MyString s1, const MyString& s2)
	{
		return !(s1 == s2);
	}

	//<<\>>的重载
	ostream& operator<<(ostream& out, const MyString& s)
	{
		for (auto e : s)
		{
			out << e;
		}
		return out;
	}
	istream& operator>>(istream& in, MyString& s)
	{
		s.clear();

		char ch;
		ch = in.get();
		char buff[128];
		size_t i = 0;
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 127)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
	//getline重载
	istream& getline(istream& in, MyString& s)
	{
		s.clear();

		char ch;
		ch = in.get();
		while (ch != '\n')
		{
			s += ch;
			ch = in.get();
		}
		return in;
	}
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值