代码格式整理-C++代码编写

目录

前言

代码编写

打包

程序运行

总结


前言

        在学习STM32开发板时,需要使用到这个开发板的源程序代码。但源程序代码的格式看起来不是很好看,有许多空白行或者每行代码开头的缩进长短不一。我一开始是通过纯手工的方式进行修改,但后面发现需要修改的代码太多了,我就想用代码实现这个功能,让修改之后的代码格式更加的工整。对于我来说写代码最看重的就是代码格式了,如果代码格式不好,那么就很难去看懂整个代码的逻辑。

修改之前的代码:

修改之后的代码:

代码编写

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<filesystem>
#include<vector>
#include<windows.h>
#include<comdef.h>
#include<climits>
#include<stack>
#include<iostream>
#include <iostream>
using namespace std;
namespace fs = std::filesystem;
bool hasReadWriteAccess(LPCTSTR filePath)//检测文件是否有读写权限
{
	DWORD attributes = GetFileAttributes(filePath);
	if (attributes == INVALID_FILE_ATTRIBUTES)
	{
		// 文件不存在或错误
		return false;
	}
	// 检查是否设置了只读属性
	if ((attributes & FILE_ATTRIBUTE_READONLY) != 0)
	{
		// 文件是只读的,所以可能没有写权限
		return false;
	}
	// 注意:这只是初步检查,不能确认具体读写权限
	return true;
}
void write_c_file_paths_to_txt(vector<string>& stringArray, string& name, int& quantity) {//将.c,.h,.cpp文件存入数组中
	// 遍历指定目录及其子目录
	for (const auto& entry : fs::recursive_directory_iterator(name))
	{
		// 检查文件是否为.c文件
		if (entry.is_regular_file() && (entry.path().extension() == ".c" || entry.path().extension() == ".h" || entry.path().extension() == ".cpp" || entry.path().extension() == ".txt"))
		{
			// 将.c文件的完整路径写入到数组中
			stringArray.push_back(entry.path().string());
			quantity++;
		}
	}
}
void Modify_1(int& L_buf, char(&buf)[10000])//将每一行末尾的Tab格式和空格清空
{
	for (int i = L_buf - 1; i >= 0; --i)
	{
		if (buf[i] == ' ' || buf[i] == '\t')
		{
			buf[i] = '\0';
		}
		else
		{
			break;
		}
	}
	L_buf = (int)(strlen(buf));//字符串的长度
}
void Modify_2(int& slash, int& L_buf, char(&buf)[10000], bool option)//将每一行开头的Tab格式和空格清空,末尾是\除外
{
	if (option == false)//用于判断是否是注释
	{
		while (slash != 1 && (buf[0] == ' ' || buf[0] == '\t'))
		{
			for (int i = 0; i < L_buf - 1; i++)
			{
				buf[i] = buf[i + 1];
			}
			buf[L_buf - 1] = '\0';
		}
		L_buf = strlen(buf);
		if (buf[L_buf - 1] == '\\')//用于记录\,并对后一行开头的Tab和空格不做处理
		{
			slash = 1;
		}
		else
		{
			slash = 0;
		}
	}
	else
	{
		while (buf[0] == ' ' || buf[0] == '\t')
		{
			for (int i = 0; i < L_buf - 1; i++)
			{
				buf[i] = buf[i + 1];
			}
			buf[L_buf - 1] = '\0';
		}
	}
	L_buf = (int)(strlen(buf));//字符串的长度
}
void Modify_3(int& L_buf, char(&buf)[10000])//用于删除‘符号’两边的空格
{
	bool signal2[10000] = {false};
	for (int i = 1; i < L_buf; ++i)
	{
		if (buf[i] == '"' && buf[i - 1] != '\\')
		{
			signal2[i] = true;
			++i;
			for (; i < L_buf; ++i)
			{
				signal2[i] = true;
				if (buf[i] == '"' && buf[i - 1] != '\\')
				{
					break;
				}
			}
		}
	}
	for (int i = L_buf - 1; i >= 0; --i)
	{
		if (signal2[i] == false && (buf[i] == '=' || buf[i] == ',' || buf[i] == ';' || buf[i] == '(' || buf[i] == ')' || buf[i] == '[' || buf[i] == ']' || buf[i] == '+' || buf[i] == '-' || buf[i] == '*' || buf[i] == '/' || buf[i] == '!' || buf[i] == '&' || buf[i] == '~' || buf[i] == '%' || buf[i] == '<' || buf[i] == '>' || buf[i] == '|' || buf[i] == '{' || buf[i] == '}'))
		{
			while (buf[i + 1] == ' ' || buf[i + 1] == '\t')
			{
				for (int j = i + 1; j < L_buf - 1; j++)
				{
					buf[j] = buf[j + 1];
				}
				buf[L_buf - 1] = '\0';
				L_buf = (int)(strlen(buf));//字符串的长度
			}
			while (buf[i - 1] == ' ' || buf[i - 1] == '\t')
			{
				for (int j = i - 1; j < L_buf - 1; j++)
				{
					buf[j] = buf[j + 1];
				}
				buf[L_buf - 1] = '\0';
				L_buf = (int)(strlen(buf));//字符串的长度
			}
		}
	}
}
void Modify_4(int& bracket, int& L_buf, char(&buf)[10000], ofstream& fout, bool option, bool& L_annotation)//用于对每一行的开头进行Tab缩进,缩进数量由bracket决定
{
	int brackets_s = 0;
	stack<pair<int,char>> s;
	bool signal2[10000] = { false };
	for (int i = 1; i < L_buf; ++i)
	{
		if (buf[i] == '"' && buf[i - 1] != '\\')
		{
			signal2[i] = true;
			++i;
			for (; i < L_buf; ++i)
			{
				signal2[i] = true;
				if (buf[i] == '"' && buf[i - 1] != '\\')
				{
					break;
				}
			}
		}
	}
	if (option == false)//用于判断是否是注释
	{
		int test = -1;//用于记录//或/*的位置
		for (int i = 0; i < L_buf - 1; ++i)
		{
			if (signal2[i] != true)
			{
				if (buf[i] == '/' && buf[i + 1] == '/')
				{
					test = i;
					break;
				}
				if (buf[i] == '/' && buf[i + 1] == '*')
				{
					L_annotation = true;
					test = i;
					if (buf[L_buf - 2] == '*' && buf[L_buf - 1] == '/')
					{
						L_annotation = false;
					}
					break;
				}
			}
		}
		if (test == -1)
		{
			test = L_buf;
		}
		if (L_buf != 0 && L_buf != 1)
		{
			for (int i = 0; i < test; ++i)
			{
				if (buf[i] == '{')
				{
					++brackets_s;
					s.push(make_pair(i, '{'));
				}
				else if (buf[i] == '}')
				{
					--brackets_s;
					if (!s.empty() && s.top().second == '{')
					{
						s.pop();
					}
					else
					{
						s.push(make_pair(i, '}'));
					}
				}
			}
			int size = s.size();
			if (brackets_s == 0)
			{
				if (buf[0] == '}')
				{
					for (int i = 0; i < bracket - 1; ++i)
					{
						fout << '\t';
					}
					fout << buf << endl;
				}
				else
				{
					for (int i = 0; i < bracket; ++i)
					{
						fout << '\t';
					}
					fout << buf << endl;
				}
			}
			else if (brackets_s < 0)
			{
				int* brackets = new int[size];
				for (int i = size - 1; i >= 0; --i)
				{
					if (!s.empty())
					{
						brackets[i] = s.top().first;
						s.pop();
					}
				}
				int j = 0;
				for (int i = 0; i < size; ++i)
				{
					if (brackets[i] != 0)
					{
						for (int k = 0; k < bracket; ++k)
						{
							fout << '\t';
						}
						for (; j < brackets[i]; ++j)
						{
							fout << buf[j];
						}
						fout << endl;
					}
					if (i == size - 1)
					{
						for (int k = 0; k < bracket - 1; ++k)
						{
							fout << '\t';
						}
						for (; j < L_buf; ++j)
						{
							fout << buf[j];
						}
						fout << endl;
						--bracket;
					}
					else
					{
						if (buf[brackets[i] + 1] == ',' || buf[brackets[i] + 1] == ';')
						{
							for (int k = 0; k < bracket - 1; ++k)
							{
								fout << '\t';
							}
							for (; j < brackets[i] + 2; ++j)
							{
								fout << buf[j];
							}
							fout << endl;
							--bracket;
						}
						else
						{
							for (int k = 0; k < bracket; ++k)
							{
								fout << '\t';
							}
							for (; j < brackets[i] + 1; ++j)
							{
								fout << buf[j];
							}
							fout << endl;
							--bracket;
						}
					}
				}
				delete[] brackets;
			}
			else
			{
				int* brackets = new int[size];
				for (int i = size - 1; i >= 0; --i)
				{
					if (!s.empty())
					{
						brackets[i] = s.top().first;
						s.pop();
					}
				}
				int j = 0;
				for (int i = 0; i < size; ++i)
				{
					if (brackets[i] != 0)
					{
						for (int k = 0; k < bracket; ++k)
						{
							fout << '\t';
						}
						for (; j < brackets[i]; ++j)
						{
							fout << buf[j];
						}
						fout << endl;
					}
					if (i == size - 1)
					{
						for (int k = 0; k < bracket; ++k)
						{
							fout << '\t';
						}
						fout << buf[j] << endl;
						++j;
						if (j + 1 < L_buf)
						{
							for (int k = 0; k < bracket + 1; ++k)
							{
								fout << '\t';
							}
							for (; j < L_buf; ++j)
							{
								fout << buf[j];
							}
							fout << endl;
						}
						++bracket;
					}
					else
					{
						for (int k = 0; k < bracket; ++k)
						{
							fout << '\t';
						}
						for (; j < brackets[i] + 1; ++j)
						{
							fout << buf[j];
						}
						fout << endl;
						++bracket;
					}
				}
				delete[] brackets;
			}
		}
		else if(L_buf == 1)
		{
			if (buf[0] == '}')
			{
				for (int i = 0; i < bracket - 1; ++i)
				{
					fout << '\t';
				}
				--bracket;
			}
			else
			{
				for (int i = 0; i < bracket; ++i)
				{
					fout << '\t';
				}
				if (buf[0] == '{')
				{
					++bracket;
				}
			}
			fout << buf << endl;
		}
	}
	else
	{
		for (int i = 0; i < bracket; ++i)
		{
			fout << '\t';
		}
		fout << buf << endl;
	}
	L_buf = (int)(strlen(buf));//字符串的长度
}
void Modify_5(char(&buf)[10000])//将buf清空
{
	for (int i = 0; i < 10000; ++i)
	{
		if (buf[i] != '\0')
		{
			buf[i] = '\0';
		}
	}
}
int main()
{
	ifstream fin;//读文件
	ofstream fout;//写文件
	string ST;//输入选项或文件路径
	const char* cp = "_COPY";
	char buf[10000] = { 0 };
	int bracket = 0;//用于记录括号
	int select = 0;//输入选项
	int slash = 0;//用于记录斜杠
	string name;//文件名
	string COPY;//复制文件名
	int record = -1;//记录所有文件是否整理成功
	bool L_annotation = false;//长注释
	bool code = false;//代码行标志
	bool _sign = false;//用于判断除空格,Tab键,以*号开头的是否是注释的结束
	bool record_t = true;//用于记录文件路径是文件还是文件夹
	int L_buf = 0;//字符串的长度
	bool mark = false;//用于记录每一行是否有双引号或单引号
	const char* filename = nullptr;//文件名
	vector<string>stringArray;//string数组
	int quantity = 0;//用于记录文件路径的数量
	while (1)
	{
		cout << "                  《《文件代码整理》》" << endl;
		cout << "提示:可以直接输入选项,文件夹和文件" << endl;
		cout << "1.继续使用当前文件,文件夹" << endl << "2.退出" << endl;
		cout << "文件是否整理成功:";
		if (record == 0)
			cout << "否" << endl;
		else if (record == 1)
			cout << "是" << endl;
		else
			cout << "" << endl;
		cout << "案例1:C:\\Users\\lenovo\\Desktop\\我的文件" << endl;
		cout << "案例2:C:/Users/lenovo/Desktop/我的文件" << endl;
		cout << "提示:输入的路径必须是绝对路径,文件中每一行处理的最大字符数为1万。" << endl;
		cout << "      文件中的\".\"只能存在在后缀名的前一位,否则文件处理会出错" << endl;
		cout << "请输入需要整理格式的文件名:";
		record_t = true;//文件夹
		quantity = 0;//用于记录文件路径的数量
		cin >> ST;
		for (int i = 0; i < ST.size(); ++i)
		{
			if (ST[i] == '\\')
			{
				ST[i] = '/';
			}
		}
		if (ST == "1")
		{
			if (name == "")
			{
				cout << "当前文件路径为空!" << endl;
				do
				{
					cout << "请重新输入:";
					cin >> name;
					if (name == "2")
					{
						cout << "系统退出" << endl;
						return 0;
					}
					else
					{
						for (int i = name.size() - 1; i >= 0; --i)
						{
							if (name[i] == '/')
							{
								for (int j = name.size() - 1; j >= i; --j)
								{
									if (name[j] == '.')
									{
										record_t = false;//文件
									}
								}
								break;
							}
						}
						if (record_t == false)
						{
							stringArray.push_back(name);
							quantity = 1;
						}
						else
						{
							write_c_file_paths_to_txt(stringArray, name, quantity);
						}
					}
				} while (name == "2");
			}
			else
			{
				for (int i = name.size() - 1; i >= 0; --i)
				{
					if (name[i] == '/')
					{
						for (int j = name.size() - 1; j >= i; --j)
						{
							if (name[j] == '.')
							{
								record_t = false;//文件
							}
						}
						break;
					}
				}
				if (record_t == false)
				{
					stringArray.push_back(name);
					quantity = 1;
				}
				else
				{
					write_c_file_paths_to_txt(stringArray, name, quantity);
				}
			}
		}
		else if (ST == "2")
		{
			return 0;
		}
		else
		{
			name = ST;//文件名
			for (int i = name.size() - 1; i >= 0; --i)
			{
				if (name[i] == '/')
				{
					for (int j = name.size() - 1; j >= i; --j)
					{
						if (name[j] == '.')
						{
							record_t = false;//文件
						}
					}
					break;
				}
			}
			if (record_t == false)
			{
				stringArray.push_back(name);
				quantity = 1;
			}
			else
			{
				write_c_file_paths_to_txt(stringArray, name, quantity);
			}
		}
		for (int i = 0; i < quantity; ++i)
		{
			for (int j = 0; j < stringArray[i].size(); ++j)
			{
				if (stringArray[i][j] == '\\')
				{
					stringArray[i][j] = '/';
				}
			}
		}
		for (int i = 0; i < quantity; ++i)
		{
			bracket = 0;
			_bstr_t bstr(stringArray[i].c_str());
			LPCTSTR lpctstrValue = (LPTSTR)bstr;
			if (hasReadWriteAccess(lpctstrValue) == true)//读写权限检测
			{
				name = stringArray[i];
				COPY = name;
				for (int i = size(name) - 1; i >= 0; i--)//创建复制文件
				{
					if (name[i] == '.')
					{
						COPY.insert(i, cp, 5);
						break;
					}
				}
				ofstream create_file(COPY);//创建COPY文件
				if (!create_file.is_open())
				{
					cout << "COPY文件创建失败,程序出现异常!- 1" << endl;
					return 0;
				}
				create_file.close();//关闭文件
				fout.open(COPY, ios::out | ios::app);
				if (fout.fail())//文件打开失败
				{
					cout << "文件打开失败,程序出现异常!- 2" << endl;
					return 0;
				}
				fin.open(name, ios::in);
				if (fin.fail())//文件打开失败
				{
					cout << "文件打开失败,程序出现异常!- 3" << endl;
					fin.close();//关闭文件
					fout.close();//关闭文件
					filename = COPY.data();
					record = 0;
					if (remove(filename) != 0)//用于删除文件
					{
						cout << "文件删除失败,请手动删除" << COPY << "文件!" << endl;
						return 0;
					}
				}
				else
				{
					while (fin.getline(buf, sizeof(buf)))
					{
						L_buf = (int)(strlen(buf));//字符串的长度
						if (slash == 1)
						{
							int signal = 0;//用于标记是否存在空格,和\t之外的字符
							for (int i = 0; i < L_buf; ++i)
							{
								if (buf[i] != ' ' && buf[i] != '\t')
								{
									signal = 1;
									break;
								}
							}
							if (L_buf == 0 || signal == 0)
							{
								fout << endl;
							}
						}
						for (int i = 0; i <= L_buf - 2; ++i)
						{
							if (buf[i] != ' ' && buf[i] != '\t')
							{
								if (buf[i] == '#')
								{
									Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
									Modify_2(slash, L_buf, buf, false);//将每一行开头的Tab格式和空格清空,末尾是\除外
									fout << buf << endl;
									break;
								}
								else if (buf[i] == '/' && buf[i + 1] == '/')
								{
									Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
									Modify_2(slash, L_buf, buf, true);//将每一行开头的Tab格式和空格清空,末尾是\除外
									Modify_4(bracket, L_buf, buf, fout, true, L_annotation);//用于对每一行的开头进行Tab缩进,缩进数量由bracket决定
									break;
								}
								else if (buf[i] == '/' && buf[i + 1] == '*')
								{
									L_annotation = true;
									Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
									if (buf[L_buf - 2] == '*' && buf[L_buf - 1] == '/')
									{
										L_annotation = false;
										Modify_2(slash, L_buf, buf, true);//将每一行开头的Tab格式和空格清空,末尾是\除外
										Modify_4(bracket, L_buf, buf, fout, true, L_annotation);//用于对每一行的开头进行Tab缩进,缩进数量由bracket决定
									}
									else
									{
										fout << buf << endl;
									}
									break;
								}
								else if (buf[i] == '*')
								{
									for (int j = i; j <= L_buf - 2; ++j)
									{
										if (buf[j] == '*' && buf[j + 1] == '/')
										{
											_sign = true;
											break;
										}
									}
									if (_sign == true)
									{
										_sign = false;
										L_annotation = false;
										Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
										fout << buf << endl;
									}
									else
									{
										if (L_annotation == true)
										{
											for (int j = 0; j < L_buf - 2; ++j)
											{
												if (buf[j] == '*' && buf[j + 1] == '/')
												{
													L_annotation = false;
													break;
												}
											}
											Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
											fout << buf << endl;
										}
										else
										{
											code = true;
										}
									}
									break;
								}
								else
								{
									if (L_annotation == true)
									{
										for (int j = 0; j < L_buf - 1; ++j)
										{
											if (buf[j] == '*' && buf[j + 1] == '/')
											{
												L_annotation = false;
												break;
											}
										}
										Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
										fout << buf << endl;
									}
									else
									{
										code = true;
									}
									break;
								}
							}
							else
								if (true)
								{
									if (buf[i + 1] == '}' || buf[i + 1] == '{' || buf[i + 1] == '(' || buf[i + 1] == ')' || buf[i + 1] == '[' || buf[i + 1] == ']' || buf[i + 1] == '<' || buf[i + 1] == '>')
									{
										code = true;
										break;
									}
								}
						}
						if (L_buf == 1)
						{
							if (L_annotation == true)
							{
								fout << buf << endl;
							}
							else
							{
								code = true;
							}
						}
						if (code == true)
						{
							code = false;
							Modify_1(L_buf, buf);//将每一行末尾的Tab格式和空格清空
							int slash_2 = slash;
							Modify_2(slash, L_buf, buf, false);//将每一行开头的Tab格式和空格清空,末尾是\除外
							if (slash_2 == 0)
							{
								Modify_3(L_buf, buf);//用于删除‘符号’两边的空格
								Modify_4(bracket, L_buf, buf, fout, false, L_annotation);//用于对每一行的开头进行Tab缩进,缩进数量由bracket决定
							}
							else
							{
								fout << buf << endl;
							}
							Modify_5(buf);//将buf清空
						}
					}
					fin.close();
					fout.close();
					ofstream truncateFile(name, ios::trunc);//清空文件内容
					fin.open(COPY, ios::in);//读文件
					if (fin.fail())//文件打开失败
					{
						cout << "文件打开失败,程序出现异常!- 4" << endl;
						return 0;
					}
					fout.open(name, ios::out | ios::app);//写文件
					if (fout.fail())//文件打开失败
					{
						cout << "文件打开失败,程序出现异常!- 5" << endl;
						return 0;
					}
					while (fin.getline(buf, sizeof(buf)))//将COPY文件中的内容全部转移到name文件中
					{
						fout << buf << endl;
						for (int i = 0; i < 10000; ++i)
						{
							if (buf[i] != '\0')
							{
								buf[i] = '\0';
							}
						}
					}
					fin.close();//关闭文件
					fout.close();//关闭文件
					filename = COPY.data();
					if (remove(filename) != 0)//用于删除文件
					{
						cout << "文件删除失败,请手动删除" << COPY << "文件!" << endl;
						record = 0;
						return 0;
					}
				}
			}
			cout << stringArray[i] << endl;
		}
		record = 1;
		system("cls");//清空终端
	}
}

        该代码的实现逻辑非常简单,这里的实现过程在代码中都有解释。

打包

        将该程序打包之后,使用会更加简单,并且可以将安装包进行分享。

        首先将Debug选项换成Release,之后再点击运行。

 

        在该项目的工程文件夹里,新建一个打包文件。

        然后再点击X64->点击Release,将.exe文件进行复制,再回到打包文件夹下面,将该exe文件粘贴到此文件夹下。

        之后需要使用到安装包打包封装工具Inno Setup v5.5.9汉化优化版。

 

        这个可以在网上直接进行免费下载。

        打开该软件选择Create a new script file using the Script Wizard(创建新的脚本文件)

        点击OK(确定)

        之后点击Next(下一步)

        这里需要设置Application name(应用程序名称),Application version(应用程序版本),APPlication publisher(应用程序发布者),Application website(应用程序网站)。

        之后点击Next(下一步)->再点击Next(下一步)

        这里需要选择要打包的exe文件的名字,不要使用他提供默认的exe文件,这里我选择了要打包的exe文件。

 

        之后点击Next(下一步)->点击Next(下一步)->点击Next(下一步)

        然后选择语言为English,这里好像没有中文版本

        之后点击Next(下一步),这里需要设置Custom compiler output folder(自定义编译器输出文件夹)就是生成文件的存放位置,Compiler output base file name(编译器输出基本文件名)就是给生成文件取名字,Custom Setup icon file(自定义安装程序图标文件)这里我没有设置,Setup password(安装密码)这里也没有设置。设置完之后点击Next(下一步)->点击Finish(完成)就OK了。

        然后点击否,生成的这一长串是脚本代码,不需要管。

        之后点击Build(构建)->点击compile(编译)->点击是,之后需要保存脚本代码,这个随便保存不需要管了。

        然后整个打包过程就完成了。

        具体的打包过程可以观看下面这个视频。C/C++编程技术讲解:好不容易做好了一个程序,想装一下B,却只会发送源码,可是朋友根本没有编译器怎么办?来,让我教你把程序打包成EXE.谁也不能阻止我装逼了._哔哩哔哩_bilibili

        这是打包好的安装包

程序运行

        安装好了之后,就会生成一个可执行文件。

        点击之后打开运行界面。

        然后在桌面上新建一个txt文件,将需要修改格式的代码复制粘贴到该txt文件上保存,之后在该程序上输入文件的绝对路径回车就可以了。

        然后txt文件里面的代码格式就修改好了。

        如果需要继续向txt文件里复制粘贴没有修改格式的代码,可以将txt文件清空,再将未修改格式的代码粘贴上去,然后保存关闭txt文件。再在程序上直接输入1就可以持续的进行修改了。

总结

        多学习知识多实践能解决更多的烦恼。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡闹的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值