轻松实现一个操作ini文件的类

CiniFile解析类 CiniFile解析类(特顺手) 参见csdn 铭毅天下 博客,内有详细描述。 立即下载

前言:

    相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。

 

一.INI简介

       那么什么是ini文件呢?ini文件是Initialization file的缩写,意即初始化文件。(从名字就可以看出它的功能了吧)。不仅你自己的程序可以使用ini文件,其实windows操作系统也有自己的ini文件---win.ini,保存在%WinDir%/system32目录下。Windows通过该文件对当前操作系统进行配置。

    ini文件里的数据的存取是采取的是预先约定好的 “项-值”存储结构,各种数据被分门别类的存储。以下是win.ini 文件的部分内容。

[Mail]

MAPI=1

CMC=1

CMCDLLNAME=mapi.dll

CMCDLLNAME32=mapi32.dll

MAPIX=1

MAPIXVER=1.0.0.1

OLEMessaging=1

                    表1

通过以上内容,我们可以看到,ini文件将各种数据分成很多以“[ ]”组成的节,而在每一个“节”中又包含了很多“项”,“项”后面紧跟着一个等号,等号后面则是该项的值。在该例中[Mail]就是一个“节”,MAPI是一个项,1则是MAPI的值。
    所以,它的通用形式我们可以总结成:

[Section]

Key=KeyValue

 

二.操作ini文件的API

windows SDK提供有两组API对ini文件进行读写。

读

写

GetPrivateProfileString

GetPrivateProfileInt

WritePrivateProfileString

GetPrivateProfileSection

WritePrivateProfileSection

GetPrivateProfileSectionNames

 

GetPrivateProfileStruct

WritePrivateProfileStruct

                                                                             表2

 

读

写

GetProfileString

GetProfileInt

WriteProfileString

GetProfileSection

WritePrivateProfileSection

                                                                             表3

    对用户的配置文件来说,一般我们使用的是表2中的函数,这一点从函数中的“private”就可以看出它是针对私有的配置文件的函数(又是废话!)。而表3中的函数则是提供给针对系统配置文件,即win.ini进行操作的函数。现只准备介绍表2中的函数,这也是使用率最高的,表3中的函数操作和表2中的函数操作类同,故略。

DWORD GetPrivateProfileString(

  LPCTSTR lpAppName,           //节名,即Section

  LPCTSTR lpKeyName,           //项名,即Key

  LPCTSTR lpDefault,                //缺省返回字符串。如lpKeyName未找到,拷贝lpDefault到lpReturnedString

  LPTSTR lpReturnedString,       //返回字符串的缓冲地址

  DWORD nSize,                       //缓冲大小

  LPCTSTR lpFileName             //ini文件路径

);

功能:根据指定的Section和 Key得到KeyValue,存放在lpReturnedString中

返回:返回拷贝到缓冲中的字符个数。不包括结束符

 

UINT GetPrivateProfileInt(

  LPCTSTR lpAppName,           //节名,即Section
 
LPCTSTR lpKeyName,           //项名,即Key

  INT nDefault,                           //缺省返回整型值。如lpKeyName未找到,函数返回nDefault的值

  LPCTSTR lpFileName             //ini文件路径

);

功能:根据指定的Section和 Key得到整型KeyValue

返回:返回得到的整型KeyValue

 

BOOL WritePrivateProfileString(

  LPCTSTR lpAppName,           //节名,即Section
 
LPCTSTR lpKeyName,           //项名,即Key

  LPCTSTR lpString,                  //要写入的字符串

  LPCTSTR lpFileName             //ini文件路径
);

功能:向指定的Section和 Key写入KeyValue。
      如果lpString为NULL,则删除当前lpKeyName

    如果lpKeyName=lpString=NULL,则删除当前Section以及其下的所有Key

       如果Section或者Key不存在,则创建;存在则覆盖

DWORD GetPrivateProfileSectionNames(

  LPTSTR lpszReturnBuffer,             //存放所有Section的缓冲地址

  DWORD nSize,                             //缓冲大小

  LPCTSTR lpFileName                   //ini文件路径

);

功能:得到ini文件中所有Section名。

返回:返回拷贝到缓冲中的字符个数。不包括结束符。
注意:返回的所有Section在缓冲中的存放格式为“Section1”,0,“Section2”,0。。。。

      若需要得到具体的每个Section,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解
      析步骤。



DWORD GetPrivateProfileSection(

  LPCTSTR lpAppName,                   //节名,即Section   

  LPTSTR lpReturnedString,              //存放指定Section下所有的Key和KeyValue的缓冲地址

  DWORD nSize,                              //缓冲大小

  LPCTSTR lpFileName                     //ini文件路径

);

功能:得到指定Section下所有的Key和KeyValue。

返回:返回拷贝到缓冲中的字符个数。不包括结束符。

注意:返回的“项-值对”在缓冲中的存放格式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0 。。。。

若需要得到具体的Key和KeyValue,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解析步骤。

GetPrivateProfileStruct和WritePrivateProfileStruct用的较少,本文也未介绍,感兴趣的朋友可以自己看看MSDN,里面也有详细介绍。

 

 

三.一个ini的类

    有了以上的API后,我们就可以轻松的制作一个简单的操作ini文件的类了。

 

//////////////////////////////////////////////////////////////////////////

// File: IniFile.h

// Date: October 2004

// Author: lixiaosan

// Email: airforcetwo@163.com

// Copyright (c) 2004. All Rights Reserved.

//////////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_)

#define AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CIniFile 

{

public:

         CIniFile();

         virtual ~CIniFile();

 

         //    设置ini文件路径
    
//    成功返回TRUE;否则返回FALSE

         BOOL         SetPath(CString strPath);

        

         //    检查section是否存在
    
//    存在返回TRUE;否则返回FALSE

         BOOL         SectionExist(CString strSection);

 

         //    从指定的Section和Key读取KeyValue
        
//    返回KeyValue

         CString         GetKeyValue(CString    strSection,

                                                        CString    strKey);        

        

         //    设置Section、Key以及KeyValue,若Section或者Key不存在则创建

         void          SetKeyValue(CString    strSection,

                                                   CString    strKey,

                                                   CString    strKeyValue);

 

         //    删除指定Section下的一个Key

         void          DeleteKey(CString strSection,

                                               CString strKey);

 

         //    删除指定的Section以及其下的所有Key

         void          DeleteSection(CString strSection);

 

         //    获得所有的Section
        
//    返回Section数目

         int              GetAllSections(CStringArray& strArrSection);

        

         //    根据指定Section得到其下的所有Key和KeyValue
        
//    返回Key的数目

         int              GetAllKeysAndValues(CString strSection,

                                                                     CStringArray& strArrKey,

                                                                     CStringArray& strArrKeyValue);

 

         //       删除所有Section

         void          DeleteAllSections();

        

private:

         //       ini文件路径

         CString m_strPath;

 

        

};

 

#endif // !defined(AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_)

 

 

 

//////////////////////////////////////////////////////////////////////////

// File: IniFile.cpp

// Date: October 2004

// Author: lixiaosan

// Email: airforcetwo@163.com

// Copyright (c) 2004. All Rights Reserved.

//////////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

//#include "test6.h"

#include "IniFile.h"

 

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

#define         MAX_SECTION                260        //Section最大长度

#define         MAX_KEY                         260        //KeyValues最大长度

#define         MAX_ALLSECTIONS     65535    //所有Section的最大长度

#define         MAX_ALLKEYS              65535    //所有KeyValue的最大长度

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CIniFile::CIniFile()

{

 

}

 

CIniFile::~CIniFile()

{

 

}

 

//////////////////////////////////////////////////////////////////////////

//   Public Functions

//////////////////////////////////////////////////////////////////////////

 

BOOL CIniFile::SetPath(CString strPath)

{

         m_strPath = strPath;

        

         //       检查文件是否存在

         DWORD  dwFlag = GetFileAttributes((LPCTSTR)m_strPath);

        

         //       文件或者路径不存在,返回FALSE

         if( 0xFFFFFFFF == dwFlag )

                   return FALSE;

        

         //       路径是目录,返回FALSE

         if (  FILE_ATTRIBUTE_DIRECTORY & dwFlag )

                   return FALSE;

 

         return TRUE;

}

 

BOOL CIniFile::SectionExist(CString strSection)

{

         TCHAR chSection[MAX_SECTION];

         DWORD dwRetValue;

 

         dwRetValue = GetPrivateProfileString(

                  (LPCTSTR)strSection,

                   NULL,

                   _T(""),

                  chSection,

                  sizeof(chSection)/sizeof(TCHAR),

                  (LPCTSTR)m_strPath);

 

         return (dwRetValue>0);

}

 

CString CIniFile::GetKeyValue(CString strSection,

                                                         CString strKey)

{

         TCHAR         chKey[MAX_KEY];

         DWORD         dwRetValue;

         CString strKeyValue=_T("");

 

         dwRetValue = GetPrivateProfileString(

                  (LPCTSTR)strSection,

                  (LPCTSTR)strKey,

                   _T(""),

                   chKey,

                  sizeof(chKey)/sizeof(TCHAR),

                  (LPCTSTR)m_strPath);      

        

         strKeyValue = chKey;

        

         return strKeyValue;

 

}

 

void CIniFile::SetKeyValue(CString strSection,

                                                 CString strKey,

                                                 CString strKeyValue)

{

         WritePrivateProfileString(

                  (LPCTSTR)strSection,

                  (LPCTSTR)strKey,

                  (LPCTSTR)strKeyValue,

                  (LPCTSTR)m_strPath);

}

 

void CIniFile::DeleteKey(CString strSection, CString strKey)

{

         WritePrivateProfileString(

                  (LPCTSTR)strSection,

                  (LPCTSTR)strKey,

                   NULL,          //       这里写NULL,则删除Key

                  (LPCTSTR)m_strPath);

}

 

void CIniFile::DeleteSection(CString strSection)

{

         WritePrivateProfileString(

                  (LPCTSTR)strSection,

                   NULL,         

                   NULL,          //       这里都写NULL,则删除Section

                  (LPCTSTR)m_strPath);

}

 

int CIniFile::GetAllSections(CStringArray& strArrSection)

{

         int dwRetValue, i, j, iPos=0;

         TCHAR chAllSections[MAX_ALLSECTIONS];

         TCHAR chTempSection[MAX_SECTION];

 

         ZeroMemory(chAllSections, MAX_ALLSECTIONS);

         ZeroMemory(chTempSection, MAX_SECTION);

 

         dwRetValue = GetPrivateProfileSectionNames(

                  chAllSections,

                  MAX_ALLSECTIONS,

                  m_strPath);

 

         //       因为Section在数组中的存放形式为“Section1”,0,“Section2”,0,0。
    
//       所以如果检测到连续两个0,则break

         for(i=0; i<MAX_ALLSECTIONS; i++)

         {

                  if( chAllSections[i] == NULL )

                   {

                            if( chAllSections[i] == chAllSections[i+1] )

                                     break;

                   }

         }

        

         i++; //         保证数据读完

         strArrSection.RemoveAll(); //         清空数组

        

         for(j=0; j<i; j++)

         {

                  chTempSection[iPos++] = chAllSections[j];

                  if( chAllSections[j] == NULL )

                   { 

                            strArrSection.Add(chTempSection);

                            ZeroMemory(chTempSection, MAX_SECTION);

                            iPos = 0;

                   }

         }

        

         return strArrSection.GetSize();

}

 

int CIniFile::GetAllKeysAndValues(CString  strSection,

                                                            CStringArray&         strArrKey,

                                                            CStringArray& strArrKeyValue)

{

         int dwRetValue, i, j, iPos=0;

         TCHAR chAllKeysAndValues[MAX_ALLKEYS];

         TCHAR chTempkeyAndValue[MAX_KEY];

         CString strTempKey;

 

         ZeroMemory(chAllKeysAndValues, MAX_ALLKEYS);

         ZeroMemory(chTempkeyAndValue, MAX_KEY);

 

         dwRetValue = GetPrivateProfileSection(

                  strSection,

                  chAllKeysAndValues,

                  MAX_ALLKEYS,

                  m_strPath);

 

         //       因为Section在数组中的存放形式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0
        
//       所以如果检测到连续两个0,则break

         for(i=0; i<MAX_ALLSECTIONS; i++)

         {

                  if( chAllKeysAndValues[i] == NULL )

                   {

                            if( chAllKeysAndValues[i] == chAllKeysAndValues[i+1] )

                                     break;

                   }

         }

        

         i++;

         strArrKey.RemoveAll();

         strArrKeyValue.RemoveAll();

        

         for(j=0; j<i; j++)

         {

                  chTempkeyAndValue[iPos++] = chAllKeysAndValues[j];

                  if( chAllKeysAndValues[j] == NULL )

                   { 

                            strTempKey = chTempkeyAndValue;

                            strArrKey.Add( strTempKey.Left(strTempKey.Find('=')) );

                            strArrKeyValue.Add( strTempKey.Mid(strTempKey.Find('=')+1) );

                            ZeroMemory(chTempkeyAndValue, MAX_KEY);

                            iPos = 0;

                   }

         }

        

         return strArrKey.GetSize();

}

 

void CIniFile::DeleteAllSections()

{

         int nSecNum;

         CStringArray strArrSection;

         nSecNum = GetAllSections(strArrSection);

         for(int i=0; i<nSecNum; i++)

         {

                  WritePrivateProfileString(

                            (LPCTSTR)strArrSection[i],

                            NULL,

                            NULL,

                            (LPCTSTR)m_strPath);      

         }

}

 

 

 

 

 

四.例子

比如在存在一个myfile.ini文件,内容如下:

[student]

number=40

male=25

female=15

average_age=15

 

[computer]

cpu=2.0

motherboard=ASUS

harddisk=120

ram=512

display=sansung

 

现在把IniFile.h和IniFile.cpp 加入到你的工程中。在使用他的类中#include “IniFile.h”;
 

         CIniFile file;

         CStringArray arrSection, arrKey, arrkeyValue;

         file.SetPath("f:// myfile.ini");

         CString str="";

 

         if(file.SectionExist("student"))

         {

                  //str="15"

                   str = file.GetKeyValue("student", "female");

                  

                   //设置number为50

                  file.SetKeyValue("student", "number", "50");

 

                   //因为在student中computer_num不存在,所以增加一项

                  file.SetKeyValue("student", "computer_num", "30");

 

                   //得到所有section

                   int num = file.GetAllSections(arrSection);

                   str = "";

                   for(int i=0; i<num; i++)

                   {

                            str += arrSection[i] + " ";//str="student computer ";

                   }

 

                   //得到所有Key和KeyValue

                   int num = file.GetAllKeysAndValues("computer", arrKey, arrkeyValue);

                   str = "";

                   for(int j=0; j<num; j++)

                   {

                            //arrKey保存了computer下所有的Key

                            //arrkeyValue保存了computer下所有的KeyValue

                            str = arrKey[j];

                            str = arrkeyValue[j];

                   }

                   //删除student下的computer_num

                  file.DeleteKey("student", "computer_num");

 

                   //删除student

                  file.DeleteSection("student");

     }


    有兴趣的朋友,可以在该类基础上进行扩展,添加你自己喜欢的功能。比如说返回int而不是字符串。
    

就讲到这里吧,欢迎大家指正。:)
 

返回:写入成功。

 

      
    现在我们来看看这几个函数的功能:

K2P padavan固件下宽带与IPTV融合 举例说下,假如你的IPTV是拨号的,IPTV端口直接连到笔记本电脑的网口,IP是自动分配的情况下,在VLC里面是可以直接播放“rtp://239.XXX.XXX.XXX:XXXX”的,即使IPTV是DHCP模式,按道理也是可以播放的。家里很少看电视,基本上就是看看春晚,然后平时老人在家没事看看,所以就把广电的机顶盒停掉了,换了一个N1的盒子刷了CoreELEC系统,既可以通过m3u8文件看网络电视,也可以看本地的多媒体,很方便,完全满足了自己的需求。在上图的第三步中,端口设置成大于1024的端口即可。 阅读详情

相关推荐

GCdepth散点图绘制

基因组组装完成后,需要对组装结果进行评估,其中GC_depth图是一个比较重要的指标,改图的横坐标是GC含量,纵坐标是平均深度。以30k为窗口(window)无overlap计算其GC含量和平均深度。如果存在样品污染,通常能够从GC含量分析中呈现出来。下文探索了几种绘制GC_depth散点图的方法思路。

huangliangbo的专栏 8993

Win32:INI文件读写结构体/Int/String/遍历

INI WritePrivateProfileString GetPrivateProfileInt WritePrivateProfileSection GetPrivateProfileSection GetPrivateProfileSectionNames

L251210269的专栏 1912

Rocky Linux 8.10下用cephadm快速搭建Ceph集群(附华为云镜像源配置)

本文详细介绍了在Rocky Linux 8.10操作系统上使用cephadm快速部署Ceph集群的实战指南,包括环境准备、系统配置、华为云镜像源优化、集群初始化及节点扩展等关键步骤。通过配置华为云镜像源,显著提升部署效率,适合企业级存储解决方案的需求。

weixin_30839881的博客 145

vc中操作INI文件函数

一 VC中操作INI文件函数 函数名 功能 备注 GetPrivateProfileInt                       读取INI文件指定块中的键名对应的整数值。   GetPrivateProfileSection 读取INI文件指定块中的所有键名及其对应值。 GetPrivateProfileSectionNames

行走 1138

AI训练加速30%!用numactl玩转多显卡绑核的隐藏技巧

本文深入探讨了如何利用Linux系统的numactl工具,通过精确的NUMA绑核策略优化多GPU AI训练性能。文章详细解析了NUMA架构对性能的影响,提供了从拓扑探查、命令实战到多卡脚本化部署的完整指南,并分享了性能验证与常见陷阱,帮助开发者实现高达30%的训练加速。

web99的专栏 448

JS+H5打字练习器

实现功能 1.导入.TXT文件到打字练习内容(部分浏览器可能出于安全问题限制了这一步操作) 2.输入文本到打字练习内(弹出输入框,将要练习的内容输入至输入框) 3. 开始练习,并根据正误在打字练习内容文本上修改颜色(某个字正确显示绿色,某个字错误,显示红色,某个字没有打显示灰色) 4.开始练习、结束练习,全部输入完成后自动结束练习,也可提前手动结束练习,结束练习后弹窗用显示时和正确率。(区别在于一个全部输入完成且全部正确,一个提前结束无其他条件) 效果图 分析 HTML 结构解析 根元素:<!DO

w11111xxxl的博客 1413

GetPrivateProfileStruct大小限制

使用WritePrivateProfileStruct和GetPrivateProfileStruct时,当写入的数据超出32766字节时,GetPrivateProfileStruct读取失败,返回字节长度不对的错误,原因如下: http://stackoverflow.com/questions/2494391/is-there-a-size-limit-on-writeprivatepro

jupiter37的专栏 2066

电磁兼容(EMC)整改案例(七):EFT测试失败都是IC悬空引脚惹的祸

无论任何时候,为了避免这些问题,通常建议对悬空的IO口进行适当的配置,比如设置为强推挽输出低电平、输入带上拉或下拉电阻等,以减少外部电路对IO管脚状态的影响,并提高系统的稳定性和可靠性.

linkking27的博客 1032

【转】轻松实现一个操作ini文件的类

 【转自http://dev.youkuaiyun.com/develop/article/46/46139.shtm】前言:    相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。 一.INI简介       那么什么是ini文件呢?ini文件是In

DryFisHH的专栏 1382

orchestrator常见问题汇总

默认的取集群名称的规则为参数决定 ,默认为取主实例 主机名 ,然后按分隔符"."之前的第一段字符为集群别名,这样在集群主库宕机后,新提升的从库的服务器名称为了新的集群名,宕机的主库成为单独的一个集群。1 默认配置文件中设置了匹配规则 ,只有被匹配的主机名才能进行故障恢复,所以该参数需要设置为 "*"3 另外配置文件中还有许多发现,恢复的忽略规则(Ignore) 这些参数也是需要注意的。由于LVS的后端的RS为IP地址,如果直接显示主机名,LVS的接口方法将无法工作。只传入脚本中用到的参数,不要多传入。

DBA之路的博客 828

huggingface下载提示huggingface_hub.errors.EntryNotFoundError:404 Client Error: (Request 1D: Root...如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1231

【原创】轻松实现一个操作ini文件的类

 作者:lixiaosan(优快云) 前言:    相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。 一.INI简介       那么什么是ini文件呢?ini文件是Initialization file的缩写,意即初始化文件。(从名

6440

【Agent从入门到实践】40 容错优化:异常处理、重试机制、降级策略

各位小伙伴,咱们的多Agent框架一路优化到现在,决策快、执行效率高、资源用得省,看似啥都行,但只要一遇到网络波动、工具故障、数据异常调用web_search工具时网络超时,整个检索任务直接失败,写作Agent没数据可用向量库连接异常,向量检索直接崩掉,依赖检索结果的Agent全趴窝单个Agent执行出错,整个并行任务流程直接中断,前功尽弃高并发下部分工具调用失败,框架没有备用方案,只能返回任务失败说白了,咱们之前的框架只有正常执行逻辑,没有异常兜底逻辑。

人工智能AI技术 908

在VB.net中操作.ini文件的通用类源代码

Option Explicit--------classIniFile.cls  代码----------------这里定义了一个classIniFile类在VB中操作.ini文件的通用类源代码Private  member  that  holds  a  reference  tothe  path  of  our  ini  filePrivate strINI

Aone --- 无限的未知 1510

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

INI文件操作类

一个方便INI文件读写的帮助类: “Kernel32.dll”中提供了ini文件操作的API函数,在C#中声明一个操作INI文件的类(如INIFile), 并将用到的函数导入类INIFile,在需要操作INI文件的地方实例化INIFile这个类,调用INIFile这个类的方法即可。 ///      ///操作INI文件      ///      internal c

popten的博客 393

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

上一篇: 体验下一代微软平台开发Visual Studio 2005
下一篇: TCP/IP researching之ARP协议浅析
xmlscript
博客等级 码龄25年 1粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值