【C++】String的模拟实现(代码实现与坑点讲解)

本篇详细介绍string底层实现的代码原理,以及相关的内容知识与写法讲解。

废话不多说,发车!!


1.头文件介绍

1.类定义和成员变量

复制代码
class string
{
public:
    typedef char* iterator;
    typedef const char* const_iterator;
private:
    char* _str;
    size_t _size;
    size_t _capacity;
    char _buff[16];
public:
    static const size_t npos;
};

主要功能模块:

  1. 类型别名定义:定义迭代器类型,便于进行字符串遍历

  2. 成员变量:

    • _str:指向动态分配字符串内存的指针

    • _size:字符串当前长度

    • _capacity:字符串容量

    • _buff[16]:小字符串优化(SSO)的缓冲区,当字符串长度小于16时使用栈内存

  3. 静态常量:npos表示无效位置,通常是-1或最大size_t

扩展:

情况 1:短字符串(SSO 启用)

复制代码
std::string s = "hello";
  • 长度 = 5 ≤ 15
  • 存在栈上 _buff[16]
  • 没有堆分配
  • 速度极快

情况 2:长字符串(SSO 关闭)

复制代码
std::string s = "this is a very long string more than 15 chars";
  • 长度 > 15
  • 用堆指针 _ptr 分配内存
  • 会调用 malloc / free

2. 迭代器接口

复制代码
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;

功能说明:提供迭代器支持,允许使用范围for循环遍历字符串,如for (char c : str)

3.构造函数、析构函数和拷贝控制

复制代码
string(const char* str = "");
~string();
string(const string& s);
string& operator=(string s);
void swap(string& s);
  • 构造函数:从C风格字符串构造,支持默认构造(空字符串)

  • 析构函数:释放动态分配的内存

  • 拷贝构造函数:实现深拷贝

  • 拷贝赋值运算符:采用拷贝并交换技术

  • 交换函数:高效交换两个字符串的内容

4. 容量和访问操作

复制代码
const char* c_str() const;
size_t size() const;
char& operator[](size_t i);
const char& operator[](size_t i) const;
void reserve(size_t n);

功能说明:

  1. c_str():返回C风格字符串指针

  2. size():返回字符串长度

  3. operator[]:支持读写和只读访问字符串元素

  4. reserve():预留容量,避免频繁重新分配内存

5. 字符串修改操作

复制代码
void push_back(char ch);
void append(const char* str);
string& operator+=(char ch);
string& operator+=(const char* str);
void pop_back();
string& insert(size_t pos, char ch);
string& insert(size_t pos, const char* str);
string& erase(size_t pos = 0, size_t len = npos);
void clear();

主要功能模块:

  1. 追加操作:push_back()append()operator+=(),在字符串末尾添加字符或字符串

  2. 删除操作:pop_back()删除最后一个字符,erase()删除指定范围的字符

  3. 插入操作:在指定位置插入字符或字符串

  4. 清空操作:clear()清空字符串内容

6. 查找和子串操作

复制代码
size_t find(char ch, size_t pos = 0) const;
size_t find(const char* str, size_t pos = 0) const;
string substr(size_t pos, size_t len = npos) const;

功能说明:

  1. 查找操作:find()查找字符或子串的位置,返回找到的位置或npos

  2. 子串操作:substr()提取子字符串

7. 比较运算符

复制代码
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;

功能说明:实现完整的比较运算符,支持字符串的字典序比较

8. 流操作符和全局函数

复制代码
ostream& operator<<(ostream& out, const string& s);
istream& operator>>(istream& in, string& s);
istream& getline(istream& is, string& str, char delim );
void swap(string& x, string& y);

功能说明:

  1. 流操作符:operator<<用于输出,operator>>用于输入

  2. getline():读取一行字符串

  3. 全局swap():交换两个字符串对象

2.函数实现

1.构造函数和析构函数

复制代码
string::string(const char* str)
	:_size(strlen(str))
{
	_capacity = _size;
	_str = new char[_size + 1]; //size没有包含/0的空间大小
	memcpy(_str, str, _size + 1);
}

string::~string()
{
	delete[]_str;
	_str = nullptr;
	_size = _capacity = 0;
}

/*string::string(const string& s)
{
	_str = new char[s._capacity + 1];
	memcpy(_str, s._str, s._size + 1);
	_size = s._size;
	_capacity = s._capacity;
}*/ 
   
string::string(const string& s)
{
	string tmp(s._str);
	swap(tmp);
}

功能说明:

  1. 从C风格字符串构造字符串对象

  2. 计算输入字符串长度并赋值给_size

  3. 设置容量等于当前长度

  4. 分配足够的内存(长度+1用于空终止符)

  5. 复制字符串内容,包括空终止符

功能说明:

  1. 析构函数:释放动态分配的内存,并将指针置空,大小和容量归零

  2. 拷贝构造函数:有两种实现方式

    • 第一种(被注释掉):传统深拷贝方式

    • 第二种:采用"拷贝并交换"技术,先创建临时对象,然后交换内容,确保异常安全

复习:

函数 功能 特点 核心区别
memcpy 内存拷贝 不处理重叠 目标和源不能重叠
memmove 内存拷贝 处理重叠 万能拷贝,最安全
memset 内存设置 按字节赋值 常用于清 0
memcmp 内存比较 按字节比较 比较前 n 个字节
复制代码
int a[5] = {1,2,3,4,5};
int b[5];

// 把 a 的 20个字节(5个int) 拷贝到 b
memcpy(b, a, 5 * sizeof(int)); 

// 内存重叠场景(memcpy会错,memmove一定对)
char arr[] = "abcdef";
memcpy(arr+2, arr, 3);  // 可能错
memmove(arr+2, arr, 3); // 一定对

int arr[10];
memset(arr, 0, 10 * sizeof(int)); // 全变0,只能设置0或-1

int a[] = {1,2};
int b[] = {1,3};
memcmp(a, b, sizeof(a)); // 返回负数

2. 交换和迭代器函数

复制代码
void string::swap(string& s)
{
	std::swap(_str, s._str);
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}

string::iterator string::begin()
{
	return _str;
}

string::iterator string::end()
{
	return _str + _size;
}

string::const_iterator string::begin() const
{
	return _str;
}

string::const_iterator string::end() const
{
	return _str + _size;
}

功能说明:

  1. swap函数:交换两个字符串的所有成员,使用了std::swap

  2. 迭代器函数:

    • begin()end():返回普通迭代器,指向字符串的开始和结束位置

    • begin() constend() const:返回const迭代器,用于const对象

  3. 支持STL风格的迭代器访问

扩展:

函数类型 写法 来源 效率 核心原理 适用场景
1. 标准库通用std::swap std::swap(a, b); <utility> 慢(需拷贝数据) 1. 创建临时变量2. 拷贝赋值3. 数据量大时很慢 int、double 等基础类型
2. 成员函数string::swap a.swap(b); 类内部实现 极快(O (1) 常数时间) 只交换内部指针、大小、容量不拷贝任何数据 stringvectorlist等容器交换首选
3. 智能查找ADL swap using std::swap;``swap(a, b); 智能匹配 智能择优 优先调用自定义高效版本没 有则用std::swap 通用模板代码(最规范写法)

3. 基本访问和容量函数

复制代码
const char* string::c_str() const
{
	return _str;
}

size_t string::size() const
{
	return _size;
}

char& string::operator[](size_t i)
{
	assert(i < _size);
	return _str[i];
}

const char& string::operator[](size_t i) const
{
	assert(i < _size);
	return _str[i];
}

功能说明:

  1. c_str():返回C风格字符串指针

  2. size():返回字符串长度

  3. operator[]:支持读写访问字符串中的字符,带边界检查

  4. operator[] const:只读访问,用于const对象

4. 内存管理和容量调整

复制代码
void string::reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		memcpy(tmp, _str, _size + 1);
		delete[]_str;
		_str = tmp;
		_capacity = n;
	}
}

功能说明:

  1. 扩容函数:增加字符串的容量

  2. **n > _capacity **时执行扩容

  3. 创建新的更大数组,复制原内容,释放旧数组

  4. 更新指针和容量值

扩展:

开辟方式 释放方式 正确 / 错误
new int delete p
new int[10] delete[] p
new int[10] delete p ❌ 泄漏
栈变量 delete p ❌ 崩溃

5. 字符串修改操作

复制代码
void string::push_back(char ch)
{
	if (_size >= _capacity)
	{
		size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
		reserve(newcapacity);
	}
	_str[_size] = ch;
	++_size;
	_str[_size] = '\0';
}

void string::append(const char* str)
{
	size_t len = strlen(str);
	if (_size+len >= _capacity)
	{
		size_t newcapacity = 2 * _capacity > _size + len ? 2 * _capacity : _size + len;
		reserve(newcapacity);
	}
	memcpy(_str + _size, str, len + 1);
	_size += len;
}
string& string::operator+=(char ch)
{
	push_back(ch);
	return *this;
}

string& string::operator+=(const char* str)
{
	append(str);
	return *this;
}

void string::pop_back()
{
	assert(_size > 0);
	--_size;
	_str[_size] = '\0';
}

功能说明:

  1. push_back:在字符串末尾添加单个字符

    • 检查容量是否足够,不足时按指数增长策略扩容

    • 添加字符,更新大小,确保以空字符结尾

  2. append:在字符串末尾追加C风格字符串

    • 计算追加字符串的长度

    • 动态扩容,选择合适的新容量**// 新容量取:2倍扩容(小) 或 直接装下(大)**

    • 复制字符串内容,更新大小

  3. operator+=:重载+=运算符,复用push_backappend

  4. pop_back:删除最后一个字符,减少大小,添加空终止符

6. 插入和删除操作

1.插入单个字符

复制代码
string& string::insert(size_t pos, char ch)
{
	assert(pos <= _size);
	if (_size >= _capacity)
	{
		size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
		reserve(newcapacity);
	}
	size_t end = _size + 1;
	while (end > pos)
	{
		_str[end] = _str[end - 1];
		--end;
	}
	_str[pos] = ch;
	++_size;
	return *this;
}

功能说明:

  1. 字符插入:在指定位置插入单个字符

  2. 检查边界,确保插入位置有效

  3. 必要时扩容

  4. 从后向前移动字符,腾出插入位置

  5. 插入字符,更新大小

2.插入字符串

复制代码
string& string::insert(size_t pos, const char* str)
{
	assert(pos <= _size);
	size_t len = strlen(str);
	if (_size + len > _capacity)
	{
		size_t newcapacity = 2 * _capacity > _size + len ? 2 * _capacity : _size + len;
		reserve(newcapacity);
	}
	size_t end = _size + len;
	while (end > pos + len - 1)
	{
		_str[end] = _str[end - len];
		--end;
	}
	for (size_t i = 0;i < len;i++)
	{
		_str[pos + i] = str[i];
	}
	_size += len;
	return *this;
}

功能说明:

1.字符串插入:在指定位置插入字符串

2.计算插入字符串长度

3.检查并调整容量****向后移动字符块

4.复制插入的字符串****更新大小

3.删除

复制代码
string& string::erase(size_t pos, size_t len)
{
	assert(pos < _size);
	if (len == npos || len >= (_size - pos))
	{
		_size = pos;
		_str[_size] = '\0';
	}
	else
	{
		size_t i = pos + len;
		memmove(_str + pos, _str + i, _size + 1 + i);
		_size -= len;
	}
	return *this;
}

功能说明:

  1. 删除子串:从指定位置开始删除指定长度的字符

  2. 检查边界

  3. 如果删除到末尾,直接截断

  4. 否则移动内存,覆盖要删除的部分

  5. 更新大小

7. 查找和子串操作

复制代码
size_t string::find(char ch, size_t pos) const
{
	for (size_t i = pos;i < _size;i++)
	{
		if (_str[i] == ch)
		{
			return i;
		}
	}
	return pos;
}

size_t string::find(const char* str, size_t pos) const
{
	const char* p1 = strstr(_str + pos, _str);
	if (p1 == nullptr)
	{
		return npos;
	}
	else
	{
		return p1 - _str;
	}
}

功能说明:

  1. 查找字符:从指定位置开始查找字符

  2. 顺序遍历字符串,找到返回位置,找不到返回npos(这里代码有误,应该是return npos而不是return pos

  3. 查找子串:使用strstr函数查找C风格子串

  4. 找到返回指针差,找不到返回npos

    复制代码
    string string::substr(size_t pos, size_t len) const
    {
    	if (len == npos || len >= _size - pos)
    	{
    		len = _size - pos;
    	}
    	string ret;
    	ret.reserve(len);
    	for (size_t i = 0;i < len;i++)
    	{
    		ret += _str[pos + i];
    	}
    	return ret;
    }

    功能说明:

  5. 提取子串:从字符串中提取指定位置开始的指定长度的子串

  6. 处理默认长度(npos)的情况

  7. 创建新字符串对象

  8. 预留足够空间

  9. 逐个字符复制

  10. 返回新字符串

8. 流操作符

复制代码
ostream& operator << (ostream& out, const string& s)
{
	for (size_t i = 0;i < s.size();i++)
	{
		out << s[i];
	}
	return out;
}

istream& operator>>(istream& in, string& s)
	{
		s.clear();//流提取前,原字符串不为空

		char buff[128];
		int i = 0;

		char ch = in.get();//避免跳过空白字符
		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;
	}

功能说明:

  1. 输出流重载:重载<<操作符,支持向输出流输出字符串

  2. 逐个字符输出到流中

  3. 输入流重载:重载>>操作符,支持向输入流输出字符串

  4. 逐个字符输入到流中

扩展:

为什么用char buff[128]而不是动态数组?

  • **栈分配速度快:在函数栈上分配,**无需动态内存管理

  • 无内存泄漏风险:函数结束时自动释放

  • 缓存友好:小数组通常能完全放入CPU缓存

9. 比较运算符

复制代码
bool string::operator<(const string& s)const
{
	size_t i1 = 0, i2 = 0;
	while (i1 < _size && i2 < s._size)
	{
		if (_str[i1] < s[i2])
		{
			return true;
		}
		else if (_str[i1] > s[i2])
		{
			return false;
		}
		else
		{
			++i1;
			++i2;
		}
	}
	return i2 < s._size;
}

bool string::operator==(const string& s) const
{
	size_t i1 = 0, i2 = 0;
	while (i1 < _size && i2 < s._size)
	{
		if (_str[i1] != s[i2])
			return false;
		else
		{
			++i1;
			++i2;
		}
	}
	return i1 == _size && i2 == s._size;
}

功能说明:

  1. 小于比较:实现字符串的字典序比较

  2. 逐个字符比较,遇到不同字符时返回比较结果

  3. 如果所有字符都相同,较短的字符串被认为更小

  4. 等于比较:比较两个字符串是否完全相同

  5. 逐个字符比较,如果长度不同或字符不同则返回false

    bool string::operator<=(const string& s) const
    {
    return *this < s || *this == s;
    }

    bool string::operator>(const string& s) const
    {
    return !(*this <= s);
    }

    bool string::operator>=(const string& s) const
    {
    return !(*this < s);
    }
    bool string::operator!=(const string& s) const
    {
    return !(*this == s);
    }

10. 输入流和交换函数

复制代码
istream& getline(istream& in, string& s, char delim)
{
	s.clear();

	char buff[128];
	int i = 0;

	char ch = in.get();
	while (ch != delim)
	{
		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;
}
void swap(string& x, string& y)
{
	x.swap(y);
}

功能说明:

  1. getline函数:从输入流读取一行(或到指定分隔符)

  2. 清空目标字符串

  3. 使用缓冲区分批读取,提高效率

  4. 读取直到遇到分隔符(默认为换行符)

  5. 处理缓冲区剩余内容

  6. 全局swap函数:调用成员函数swap

3.全局代码

1.头文件

复制代码
#pragma once
#include<iostream>
#include<assert.h>
#include<string.h>

using namespace std;

namespace wxx
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;

		iterator begin();
		iterator end();

		const_iterator begin() const;
		const_iterator end() const;

		//string();
		string(const char* str = "");
		const char* c_str() const;
		~string();
		string(const string& s);
		string& operator=(string s);
		void swap(string& s);

		size_t size() const;
		char& operator[](size_t i);
		const char& operator[](size_t i) const;

		void reserve(size_t n);

		void push_back(char ch);
		void append(const char* str);
		string& operator+=(char ch);
		string& operator+=(const char* str);

		void pop_back();

		string& insert(size_t pos, char ch);
		string& insert(size_t pos, const char* str);
		string& erase(size_t pos = 0, size_t len = npos);

		size_t find(char ch, size_t pos = 0) const;
		size_t find(const char* str, size_t pos = 0)  const;

		string substr(size_t pos, size_t len = npos) const;
		void clear();
		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;
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		// _size < 16 串存在buff数组中
		// _size >= 16 串存在_str指向的数组中
		char _buff[16];
	public:
		static const size_t npos;
	};
	ostream& operator<<(ostream& out, const string& s);
	istream& operator>>(istream& in, string& s);
	istream& getline(istream& is, string& str, char delim = '\n');
	void swap(string& x, string& y);
}

2.源文件

复制代码
#include"string.h"

namespace wxx
{
	const size_t string::npos = -1;

	string::string(const char* str)
		:_size(strlen(str))
	{
		_capacity = _size;
		_str = new char[_size + 1];
		memcpy(_str, str, _size + 1);
	}

	string::~string()
	{
		delete[]_str;
		_str = nullptr;
		_size = _capacity = 0;
	}

	/*string::string(const string& s)
	{
		_str = new char[s._capacity + 1];
		memcpy(_str, s._str, s._size + 1);
		_size = s._size;
		_capacity = s._capacity;
	}*/
	string::string(const string& s)
	{
		cout << "string::string(const string& s)" << endl;

		string tmp(s._str);
		swap(tmp);
	}

	void string::swap(string& s)
	{
		std::swap(_str, s._str);
		std::swap(_size, s._size);
		std::swap(_capacity, s._capacity);
	}

	string::iterator string::begin()
	{
		return _str;
	}

	string::iterator string::end()
	{
		return _str + _size;
	}

	string::const_iterator string::begin() const
	{
		return _str;
	}

	string::const_iterator string::end() const
	{
		return _str + _size;
	}

	const char* string::c_str() const
	{
		return _str;
	}

	size_t string::size() const
	{
		return _size;
	}

	char& string::operator[](size_t i)
	{
		assert(i < _size);
		return _str[i];
	}

	const char& string::operator[](size_t i) const
	{
		assert(i < _size);
		return _str[i];
	}

	void string::reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			memcpy(tmp, _str, _size + 1);
			delete[]_str;
			_str = tmp;
			_capacity = n;
		}
	}

	void string::push_back(char ch)
	{
		if (_size >= _capacity)
		{
			size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(newcapacity);
		}
		_str[_size] = ch;
		++_size;
		_str[_size] = '\0';
	}

	void string::append(const char* str)
	{
		size_t len = strlen(str);
		if (_size+len >= _capacity)
		{
			size_t newcapacity = 2 * _capacity > _size + len ? 2 * _capacity : _size + len;
			reserve(newcapacity);
		}
		memcpy(_str + _size, str, len + 1);
		_size += len;
	}

	string& string::operator+=(char ch)
	{
		push_back(ch);
		return *this;
	}

	string& string::operator+=(const char* str)
	{
		append(str);
		return *this;
	}

	void string::pop_back()
	{
		assert(_size > 0);
		--_size;
		_str[_size] = '\0';
	}

	string& string::insert(size_t pos, char ch)
	{
		assert(pos <= _size);
		if (_size >= _capacity)
		{
			size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(newcapacity);
		}
		size_t end = _size + 1;
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			--end;
		}
		_str[pos] = ch;
		++_size;
		return *this;
	}

	string& string::insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t len = strlen(str);
		if (_size + len > _capacity)
		{
			size_t newcapacity = 2 * _capacity > _size + len ? 2 * _capacity : _size + len;
			reserve(newcapacity);
		}
		size_t end = _size + len;
		while (end > pos + len - 1)
		{
			_str[end] = _str[end - len];
			--end;
		}
		for (size_t i = 0;i < len;i++)
		{
			_str[pos + i] = str[i];
		}
		_size += len;
		return *this;
	}

	string& string::erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		if (len == npos || len >= (_size - pos))
		{
			_size = pos;
			_str[_size] = '\0';
		}
		else
		{
			size_t i = pos + len;
			memmove(_str + pos, _str + i, _size + 1 + i);
			_size -= len;
		}
		return *this;
	}

	size_t string::find(char ch, size_t pos) const
	{
		for (size_t i = pos;i < _size;i++)
		{
			if (_str[i] == ch)
			{
				return i;
			}
		}
		return pos;
	}

	size_t string::find(const char* str, size_t pos) const
	{
		const char* p1 = strstr(_str + pos, _str);
		if (p1 == nullptr)
		{
			return npos;
		}
		else
		{
			return p1 - _str;
		}
	}

	string string::substr(size_t pos, size_t len) const
	{
		if (len == npos || len >= _size - pos)
		{
			len = _size - pos;
		}
		string ret;
		ret.reserve(len);
		for (size_t i = 0;i < len;i++)
		{
			ret += _str[pos + i];
		}
		return ret;
	}

	ostream& operator << (ostream& out, const string& s)
	{
		for (size_t i = 0;i < s.size();i++)
		{
			out << s[i];
		}
		return out;
	}
	istream& operator>>(istream& in, string& s)
	{
		s.clear();

		char buff[128];
		int i = 0;

		char ch = in.get();
		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;
	}


	bool string::operator<(const string& s)const
	{
		size_t i1 = 0, i2 = 0;
		while (i1 < _size && i2 < s._size)
		{
			if (_str[i1] < s[i2])
			{
				return true;
			}
			else if (_str[i1] > s[i2])
			{
				return false;
			}
			else
			{
				++i1;
				++i2;
			}
		}
		return i2 < s._size;
	}

	bool string::operator==(const string& s) const
	{
		size_t i1 = 0, i2 = 0;
		while (i1 < _size && i2 < s._size)
		{
			if (_str[i1] != s[i2])
				return false;
			else
			{
				++i1;
				++i2;
			}
		}
		return i1 == _size && i2 == s._size;
	}

	bool string::operator<=(const string& s) const
	{
		return *this < s || *this == s;
	}


	bool string::operator>(const string& s) const
	{
		return !(*this <= s);
	}

	bool string::operator>=(const string& s) const
	{
		return !(*this < s);
	}
	bool string::operator!=(const string& s) const
	{
		return !(*this == s);
	}
	istream& getline(istream& in, string& s, char delim)
	{
		s.clear();

		char buff[128];
		int i = 0;

		char ch = in.get();
		while (ch != delim)
		{
			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;
	}
	void swap(string& x, string& y)
	{
		x.swap(y);
	}
};

相关推荐
良木生香1 小时前
【C++初阶】STL——Vector从入门到应用完全指南(1)
开发语言·c++·神经网络·算法·计算机视觉·自然语言处理·数据挖掘
憨波个1 小时前
【说话人日志】DOVER:diarization 输出融合算法
人工智能·算法·音频·语音识别·聚类
skilllite作者1 小时前
Zed 1.0 编辑器深度评测与实战指南
开发语言·人工智能·windows·python·编辑器·agi
爱学习的张大1 小时前
具身智能论文问答(四):pi0
人工智能·算法
楼田莉子1 小时前
仿Muduo的高并发服务器:Channel模块与Poller模块
linux·服务器·c++·学习·设计模式
zhouwy1131 小时前
Linux网络编程从入门到精通
linux·c++
迷途之人不知返1 小时前
deque的简单认识
数据结构·c++
上弦月-编程1 小时前
指针编程:高效内存管理核心
java·数据结构·算法
罗超驿1 小时前
双指针算法经典案例:LeetCode 283. 移动零(Java详解)
java·算法·leetcode