收藏 分销(赏)

C++实习报告.doc

上传人:二*** 文档编号:4570192 上传时间:2024-09-30 格式:DOC 页数:24 大小:2.79MB 下载积分:5 金币
下载 相关 举报
C++实习报告.doc_第1页
第1页 / 共24页
本文档共24页,全文阅读请下载到手机保存,查看更方便
资源描述
. . 一、实习目的 《C++语言课程设计》实习是遥感科学与技术专业的一门专业必修课程。本课程选择VS2010作为开发环境,C++语言作为编程环境,C++语言作为编程工具,将面向对象的程序设计方法、类和对象的创建和使用、文件读写操作、MFC编程等几个重要知识点作为实习容,旨在让学生在较短时间熟悉C++软件系统开发的实际工作流程,包括需求分析、软件设计、软件开发、软件调试等,使得学生在理论学习的基础上,进一步对所学知识点进行深入应用,达到培养学生的C++编程能力,最终实现学以致用的目的。 二、 任务及要求 1.掌握C++软件系统开发的基本思路,完成C++软件程序的设计文档; 2.熟练掌握C++语言的基本语法,包括函数的定义和调用,顺序结构、选择结构、循环结构的使用等; 3.熟练掌握C++语言面对对象的程序设计方法,学会根据实际问题设计对象,包括对象的数据成员和成员函数; 4.在对象的设计和封装的基础上,熟练掌握类的抽象和定义方法; 5.熟练掌握类的继承方法; 6.熟练掌握多态性的实现方法,包括动态多态和静态多态; 7.熟练掌握利用C++语言实现文本文件的格式化读写操作; 8.掌握基于VS2010开发环境的界面程序设计和开发工作。 二、 软件设计 1.功能说明 本次的实习容为基于VS2010开发环境,利用C++语言实现一个简单的学生信息管理系统,用于学生信息的录入、存储,并能提供查询、删除、修改等基本操作。详细功能有学生信息、学生信息的录入、存储、学生信息的查询、学生信息的删除和学生信息的修改。 在实现学生信息查询的基础上,对查询结果进行修改操作,用户在软件界面中重新输入对应学生的信息,系统根据输入信息在默认文本文件中对学生信息进行更新。 2.系统功能模块设计 将软件功能划分为5个不同的子模块: 学生信息管理系统 用户登录 主界面 信 息 修 改 信 息 录 入、存 储 信 息 删 除 信 息 查 询 学 生 信 息 3.模块功能设计 (1)学生基本信息管理模块:学生基本信息包括:学号、、性别、年龄、专业、学历(分为本科和研究生两类)6项。此外,研究生还包括导师、研究生类别(分为硕士和博士两类)两种属性,而本科生包括社团属性。 (2)学生信息的录入、存储模块:主要功能包括:学生信息的录入,用户通过软件界面将学生基本信息录入系统;学生信息的存储,系统将用户录入的信息保存在系统默认的文本文件中。 通过选择“本科生”或“研究生”两个单选按钮,确定学生的学历信息,进而根据不同学生类别所应具有的属性,对无用属性的输入框进行屏蔽。在“学号”对应的输入位置输入学生学号;在“”对应的输入位置输入学生;在“性别”对应的输入位置输入学生性别;在“年龄”对应的输入位置输入学生年龄;在“专业”对应的输入位置输入学生专业;在“社团”对应的输入位置输入本科生所属社团;在“导师”对应的输入位置输入研究生导师;在“类型”对应的输入位置输入研究生类别(“硕士”或“博士”)。点击“确定”按钮,在主界面所选择的文件中写入学生信息。 为学号文本框添加Cstring类型成员变量;为文本框添加Cstring类型成员变量;为性别文本框添加Cstring类型成员变量;为年龄文本框添加Cstring类型成员变量;为专业文本框添加Cstring类型成员变量;为社团文本框添加Cstring类型成员变量;为导师文本框添加Cstring类型成员变量;为类别文本框添加Cstring类型成员变量。设置“本科生”单选按钮的Group属性为Ture,此时“本科生”和“研究生”默认构成一组单选按钮,为本科生单选按钮添加int类型成员变量,选中“本科生”时变量值为0,选中“研究生”时变量值为1。 (3)学生信息的查询:用户通过软件界面输入学生学号对学生基本信息进行查询操作,系统在默认文本文件中查找对应学生的信息,将查询结果显示在软件界面中。在指定位置输入要查找的学生学号。点击“查询”按钮,实现在文件中查找指定学生信息的功能,若未找到,弹出提示信息。查找完成后“”、“学历”、“性别”、“年龄”、“专业”的对应位置显示查找的结果。 为文本框添加Cstring类型成员变量;为性别文本框添加Cstring类型成员变量;为学历文本框添加Cstring类型成员变量;为年龄文本框添加Cstring类型成员变量;为专业文本框添加Cstring类型成员变量。 (4)学生信息的删除:在实现学生信息查询的基础上,对查询结果进行删除操作,系统在默认文本文件中删除对应学生的基本信息。在指定位置输入要删除的学生学号。点击“删除”按钮,实现在文件中删除指定学生信息的功能。为学号文本框添加Cstring类型成员变量。 (5)学生信息的修改:在实现学生信息查询的基础上,对查询结果进行修改操作,用户在软件界面中重新输入对应学生的信息,系统根据输入信息在默认文本文件中对学生信息进行更新。在指定位置输入要修改的学生学号。点击“查找”按钮,在下方的“”、“性别”、“年龄”、“专业”对应位置显示学生的原始信息,若查找失败,则弹出提示信息。在“”、“性别”、“年龄”、“专业”对应位置输入学生的新信息。点击“保存”按钮,用学生的新信息替换学生的原始信息。 为文本框添加Cstring类型成员变量;为性别文本框添加Cstring类型成员变量;为年龄文本框添加Cstring类型成员变量;为专业文本框添加Cstring类型成员变量。 4.类的设计 采用面对对象的编程思想对其进行抽象和封装,从而设计出能够描述不同数据的类(包括数据成员、成员函数): (1)学生类 数据成员(均定义为Cstring类型):学号、、性别、年龄、专业、学历。 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 (2)本科生类 数据成员(均定义为Cstring类型):参加的社团 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 (3)研究生类 数据成员(均定义为Cstring类型):导师、研究生类别(分为硕士和博士两类) 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 研究生类 继承 本科生类 继承 学生类 各类之间的关系是: 三、软件界面设计 1.创建MFC工程 在VS2010开发环境主界面下中选择“新建项目”,打开新建项目对话框,选择Visual C++语言下的MFC→MFC应用程序(MFC Application),在下方“名称”文本框中输入项目名称“StudlnfoSys”,在“位置”文本框中选择项目程序文件保存路径,设置完成后,点击确定按钮打开MFC应用程序向导。 图一选择应用程序类型 图二选择用户功能 图三高级功能 图四生成的类 图五空的对话框应用程序框架 2.添加对话框资源 (1)设置对话框属性 在程序对话框中点击鼠标右键,在弹出菜单中选择“属性”菜单项,窗口右侧打开“属性”窗口,设置对话框的ID、标题、字体、边界样式等属性。 图六属性表 (2)添加控件 在窗口最右侧的选项卡列表中打卡“工具箱”,包括了多种控件,通过鼠标的拖曳操作,可将工具箱中的控件添加到对话框,同时通过拖曳还可调整控件的大小。在程序中各种控件均由类实现,当对话框中添加一个控件时,软件会自动在程序中创建一个对象,并调用构造函数,当对话框关闭时,其各个子控件对象被销毁。此外也可以自己在程序中写代码创建、显示控件对象。 添加控件后,在控件上点击右键,在弹出菜单中选择“属性”菜单项,打开属性窗口,以按钮控件为例,在窗口中可以设置按钮的ID、文字、样式等。 (3)添加对话框 在资源视图中选择“Dialog”,右键点击,在弹出菜单中选择“插入Dialog”菜单项,系统自动在工程中添加默认对话框,可以按上文的方法设置新的对话框属性。 根据学生信息管理系统的功能要求,需要添加四种功能的相应对话框,如下图所示: 图七学生信息管理系统对话框 图八录入信息对话框 图九删除信息对话框 图十查找信息对话框 图十一修改信息对话框 3.对话框的设置 (1)为对话框创建类 程序主界面的对话框创建完成后,系统自动会为其创建类,此时程序的主界面就是由该类创建的一个对象,而在主界面的基础上添加新对话框后,系统不再自动为新对话框创建类,若要使用该对话框,就需要自行创建对应的类:在新对话框中点击鼠标右键,在弹出菜单中选择“添加类”菜单项,打开“MFC添加类向导”窗口,在“类名”后的文本框中输入为新对话框所创建的对应类的类名。 图十二类的创建 在类创建完成后,可以看到在工程的文件视图中自动生成了头文件和源文件,分别包含了类的声明和实现。 (2)为对话框控件添加成员变量 在程序中对某一控件值进行修改,可以在对话框点击鼠标右键,在弹出菜单中选择“类向导”菜单项,打开“类向导”窗口,在“类名”下拉列表中选择一个对话框类,选中成员变量,此时下方的“成员变量”列表会列出该对话框中所有控件的ID,点击右侧的添加变量,给每一个成员变量添加变量。 在窗口左侧设置成员变量的访问权限,默认为“public”,文件路径为字符串类型的数据,因而要为其添加一个字符串类型的成员,“变量类型”选择“CString”,变量名通常以m_开头,“_”后的第一个字符表示成员的数据类型。 图十三添加成员变量 (3)为对话框添加消息处理函数 通过上述步骤创建的对话框,其中的所有控件仍无法实现功能,若要其发挥作用,需要为对应控件添加消息处理函数。 在“类向导”窗口中的“类名”下拉列表中选择界面对应的类,窗口中部选择“命令”选项卡,在下方的“对象ID”列表中选择对象,在右侧“消息”列表中列出该按钮的默认支持的消息,其中“BN_CLICKED”为单机按钮操作,将其选中,点击右侧的“添加处理程序”按钮,打开“添加成员函数”窗口,系统会根据按钮的ID自动为消息处理函数命名。 在“类向导”窗口下方的“成员函数”列表中选择刚刚添加过得函数,然后点击右侧的“编辑代码”状态进行代码编辑。 图十四添加处理程序 三、 系统功能实现 1. 类的定义 (1)学生类 数据成员(均定义为Cstring类型):学号、、性别、年龄、专业、学历。 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 具体代码如下: /************************源文件容*****************************/ #include "stdafx.h" #include "StudlnfoSys.h" #include "Student.h" //构造函数的实现 Student::Student(CString number,CString name,CString sex,CString age,CString major,CString level) { this->number=number; this->name=name; this->sex=sex; this->age=age; this->major=major; this->level=level; } //信息获取函数的实现 CString Student::getInfo() { CString info="";//定义字符串,存放信息 //格式字符串,所有信息用“-”分隔 info.Format("%s-%s-%s-%s-%s-%s\n",this->level,this->number,this->name,this->sex, this->age, this->major); return info;//返回信息字符串 } (2)本科生类 数据成员(均定义为Cstring类型):参加的社团 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 具体代码如下: /**************************源文件容***************************/ #include "stdafx.h" #include "StudlnfoSys.h" #include "Benke.h" #include "stdafx.h" IMPLEMENT_DYNAMIC(Benke, Student) //构造函数的实现,调用父类构造函数 //信息获取函数,与父类函数同名 Benke::Benke(CString number, CString name, CString sex, CString age, CString major, CString level, CString corporation):Student(number,name,sex,age,major,level) { this-> m_sCorporation=corporation; } //信息获取函数,与父类函数同名 CString Benke::getInfo() { CString info="" info.Format("%s-%s-%s-%s-%s-%s-%s\n", this->level,this->number,this->name, this->sex, this->age, this->major, this->m_sCorporation); return info;//返回信息字串 } (3)研究生类 数据成员(均定义为Cstring类型):导师、研究生类别(分为硕士和博士两类) 成员函数:构造函数,功能为利用界面输入的信息初始化数据成员。信息获取函数,功能为将所有信息添加在一个字符串中,并将该字符串返回。 具体代码如下: /**************************源文件容***************************/ #include "stdafx.h" #include "StudlnfoSys.h" #include "Yyanjiu.h" //构造函数的实现,调用父类构造函数 IMPLEMENT_DYNAMIC(Yyanjiu, CWnd) Yyanjiu::Yyanjiu(CString number, CString name, CString sex, CString age, CString major, CString level, CString tutor, CString type):Student(number,name,sex,age,major,level) { this->m_sTutor =tutor; this->m_sType =type; } //信息获取函数,与父类函数同名 CString Yyanjiu::getInfo(){ CString info = ""; info.Format("%s-%s-%s-%s-%s-%s-%s-%s\n", this->level,this->number,this->name, this->sex, this->age, this->major, this->m_sTutor,this->m_sType); return info;//返回信息字符串 } 2. 系统主模块 具体代码如下: /**************************单击“浏览”按*************************/ CString filePath = "";//定义全局变量,存放文件路径 void CStudlnfoSysDlg::OnBnClickedButtonFile() { CFileDialog fileDlg(TRUE, NULL, OFN_OVERWRITEPROMPT, "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*");//定义选择文件的对话框 if(fileDlg.DoModal() == IDOK){ //弹出选择文件的对话框 filePath = fileDlg.GetPathName(); //返回选择的文件名 m_sFile = filePath; //将文件名显示到文本框 UpdateData(FALSE);//更新控件容 FILE *fp;//定义文件指针 fopen_s(&fp, filePath, "r");//以只读方式打开文件 if (fp == NULL) //判断文件是否不存在 fopen_s(&fp, filePath, "w");//如果文件不存在,创建文件 fclose(fp);//关闭文件 } } /**********************单击“查找信息”按钮***********************/ void CStudlnfoSysDlg::OnBnClickedButtonSearch() { CSearchDlg *gld = new CSearchDlg();//创建查找信息对话框 dlg->DoModal();//弹出查找信息对话框 } /**********************单击“删除信息”按钮***********************/ void CStudlnfoSysDlg::OnBnClickedButtonDelet() { CDeletDlg *gld = new CDeletDlg();//创建删除信息对话框 dlg->DoModal();//弹出删除信息 } /**********************单击“修改信息”按钮***********************/ void CStudlnfoSysDlg::OnBnClickedButtonUpdate() { CUpdateDlg *gld = new CUpdateDlg();//创建修改信息对话框 dlg->DoModal();//弹出修改信息 } /**********************单击“退出系统”按钮***********************/ void CStudlnfoSysDlg::OnBnClickedButtonQuit() { EndDialog(IDOK); //关闭对话框 } 3. 录入信息模块 /********************单击“本科生”单选按钮*********************/ void CInDlg::OnBnClickedRadioBenke() { GetDlgItem(IDC_EDIT_Corp)->EnableWindow(TRUE);//设置社团输入位置为可用 GetDlgItem(IDC_EDIT_Tutor)->EnableWindow(FALSE);//设置导师输入位置为禁用 GetDlgItem(IDC_EDIT_Type)->EnableWindow(FALSE);//设置类型输入位置为禁用 } /********************单击“研究生”单选按钮*********************/ void CInDlg::OnBnClickedRadioYyanjiu() { GetDlgItem(IDC_EDIT_Corp)->EnableWindow(TRUE);//设置社团输入位置为禁用 GetDlgItem(IDC_EDIT_Tutor)->EnableWindow(FALSE);//设置导师输入位置为可用 GetDlgItem(IDC_EDIT_Type)->EnableWindow(FALSE);//设置类型输入位置为可用 } /*************************单击“确定”按钮***********************/ #include "Benke.h" #include "Yyanjiu.h" #include <iostream> #include <fstream> using namespace std; extern CString filePath;//引入全局变量,获取主界面中的文件路径 void CInDlg::OnBnClickedOk() { UpdateData(TRUE);//更新窗口 CString info = "";//定义字符串,用于储存学生信息 if (this->m_iStudType == 0){ //如果选中“本科生” Benke *p = new Benke( //利用界面中输入的信息创建本科生对象) this->m_sNumber, this->m_sName, this->m_sSex, this->m_sAge, this->m_sMajor, "本科生", this->m_sCorp); info = p->getInfo();//保存本科生信息 } if (this->m_iStudType == 1){ // 如果选中“研究生” Yyanjiu *p = new Yyanjiu(//利用界面中输入的信息创建研究生对象) this->m_sNumber, this->m_sName, this->m_sSex, this->m_sAge, this->m_sMajor, "研究生", this->m_sTutor, this->m_sType); info = p->getInfo();//保存研究生信息 } ofstream out;//写操作的文件类,需添加头文件iostream和fstream //ios::app表示以在末尾追加的方式写入文件 out.open(filePath, ios::app);//打开文件 out.write(info, info.GetLength());//写入信息 out.close();//关闭文件 MessageBox("信息录入完成");//完成提示 CInDlg *dlg = new CInDlg();//创建新的录入信息对话框 dlg->DoModal();//弹出录入信息对话框 EndDialog(IDOK);//关闭旧的对话框 } 4. 查找信息模块 /*************************单击“查找”按钮***********************/ #include <iostream> #include <fstream> #include <string> using namespace std; extern CString filePath;//引入全局变量,获取主界面中的文件路径 void CSearchDlg::OnBnClickedButton1() { UpdateData(TRUE);//更新窗口 string info[6];//定义字符串数组,存储读取的学生各项信息 ifstream in;//需添加头文件iostream和fsteream //ios::in表示以只读方式打开文件 in.open(filePath, ios::in); //打开文件 string strline; //定义字符串,存储文件中读取的一行容 int i = 0;//循环变量 while(getline(in, strLine)) { //逐行读取文件容,需添加头文件string if(CString.find(this->m_sSnumber) !=-1) { //在一行容中匹配学号 int pos = 0; int pre_pos = 0; while (pos != -1 && i < 6) { pre_pos = pos; pos = strLine.find('-' (pos + 1)) + 1;//查找分隔符 //根据分隔符对字符串进行分段读取 info[i++] = strLine.substr(pre_pos, (pos - pre_pos - 1)); } //将分段读取出的容分别赋给对应的属性 this->m_sSlevel = info[0].c_str(); this->m_sSname = info[2].c_str(); this->m_sSsex = info[3].c_str(); this->m_sSage = info[4].c_str(); this->m_sSmajor = info[5].c_str(); UpdateData(FALSE); //更新窗口 in.close();//关闭文件 return;//查找成功,程序返回 } } MessageBox("该学生信息未找到!");//查找失败,弹出提示 } 5. 删除信息模块 /*************************单击“删除”按钮***********************/ #include <iostream> #include <fstream> #include <string> using namespace std; extern CString filePath;//引入全局变量,获取主界面中的文件路径 void CDeletDlg::OnClickedButton1() { UpdateData(TRUE);//更新窗口 ifstream in; //读操作的文件夹,需添加头文件iostream和fstream //ios::in表示以只读的方式打开文件 in.open(filePath, ios::in); //打开文件 string strLine; string content[100];//定义字符串数组,存放文件容 int count = 0;// 学生总数 int i = 0;//循环变量 while (getline(in, strLine)) { //逐行读取文件容,需添加头文件string count++; //每读取一行,学生总数加1 if (strLine.find(this->m_sNumber) == -1){ //在一行容中匹配学号 content[i++] = strLine + '\n'; //若与输入学号不同,则存储该学生信息 } } in.close(); //关闭文件 if (i == count) { //保留信息的学生数量等于学生总数,说明没有学生被找到 MessageBox("该学生信息未被找到!"); return; } ofstream out;//写操作的文件类,需添加头文件iostream和fstream //ios::out表示以写入方式打开文件 out.open(filePath, ios::out); //打开文件 //在新文件中写入存储的容,其中剔除了指定学号的学生信息 for (int j = 0; j < i; j++) { CString dtr = content[j].c_str(); out.write(str,str.GetLength()); // 文件写入 } out.close();//关闭文件 MessageBox("学生信息删除成功!"); } 6. 修改信息模块 /*************************单击“查找”按钮***********************/ extern CString filePath;//引入全局变量,获取主界面中的文件路径 CString content[100];//定义全局字符串数组,存储读取的学生各项信息 void CUpdateDlg::OnClickedButtonSearch() { UpdateData(TRUE);//更新窗口 ifstream in; //需添加头文件iostream和fstream in.open(filePath, ios::in); CString strLine; // 定义字符串,存储文件中读取的一行容 int i = 0, j = ;//循环变量 while (getline(in, strLine)) {//逐行读取文件容,需添加头文件string if (strLine.find(this->m_sNumber) != -1){ //在一行容中匹配学号 int pos = 0; int pre_pos = 0; while (pos != -1 && i < 8) { pre_pos = pos; pos = strLine.find('-',(pos + 1)) + 1; //查找分隔符 //根据分隔符对字符串进行分段读取 info[i++] = strLine.substr(pre_pos, (pos - pre_pos - 1)); } //将分段读取出的容分别赋给对应的属性 this->m_sName = info[2].c_str(); this->m_sSex = info[3].c_str(); this->m_sAge = info[4].c_str(); this->m_sMajor = info[5].c_str(); UpdateData(FALSE); } else { content[j++] = strLine + '\n'; //若与输入学号不同,则存储该学生信息 } } in.close();// 关闭文件 if (i == 0) { //i =0说明匹配失败 MessageBox("该学生信息未找到"); } /*************************单击“保存”按钮***********************/ void CUpdateDlg::OnClickedButtonSave() { UpdateData(TRUE);//更新窗口 CString studInfo; //存储修改后的学生信息 if (info[0] == "本科生") { //如果学历为本科生,则创建本科生对象 Benke *p = new Benke( this->m_sNumber, this->m_sName, this->m_sSex, this->m_sAge, this->m_sMajor, "本科生", info[6].c_str()); studInfo = p->getInfo(); //保存本科生信息 } if (info[0] == "研究生") { //如果学历为研究生,则创建研究生对象 Yyanjiu *p = new Yyanjiu( this->m_sNumber, this->m_sName, this->m_sSex, this->m_sAge, this->m_sMajor, "研究生", info[6].c_str(), info[7].c_str()); studInfo = p->getInfo(); //保存本科生信息 } int i = 0; while (content[i] !="") i++;//找到文件中最后一条学生信息的位置 content[i] = studInfo.GetBuffer(0); //在最后一条信息之后添加修改后的信息 } ofstream out; //ios::out表示以写入方式打开文件 out.open(filePath, ios::out); //打开文件 //在新文件中写入存储的容,其中剔除了指定学号的学生信息 for (int j = 0; j < i; j++) { CString dtr = content[j].c_str(); out.write(str, str.GetLength()); // 文件写入 content[j] == "";//将已经西而入的容清空 } out.close(); //关闭文件 MessageBox("学生信息修改成功!"); } 四、实习总结 经过为期一周的《C++语言课程设计》实习,收获颇丰。在这一周的时间里,我对VS2010软件有了一个深刻的了解以及对基本操作的掌握。 这一周重点在于进行MFC的编程,其中包括需求设计、软件设计等。在软件编程方面学会了一个基本的操作步骤,就是先得有一个基本的设计思路,然后在进行具体容的编写。在操作中渐渐熟悉了一些语法的使用,包括函数的定义和调用等。练习了如何根据实际问题设计对象,包括对象的数据成员和成员函数。 在界面设计操作的过程中学会了要时刻注意成员属性的设置,在代码编写操作的过程中学会了要注意字符输入时的中英文切换,以及头文件的调用。 总之,一周的实习感触良多,收获颇深,希望以后可以继续熟练软件的编程操作。 - 优选
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 应用文书 > 报告/总结

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服