cocos2d-x中中文乱码解决

Cocos2d-x 学习随记二 Boost::Locale解决中文乱码问题 一、Cocos2d-x 引擎编码格式默认为utf8,而 阅读详情

在cocos2d-x中直接显示中文的时候会出现乱码,虽然在实际开发中把字符串直接写在代码里也不是好的做法,但是有时候也是为了更方便了。
本文采用两种方案来解决这个问题:
1. 使用iconv,引擎也提供了这个库,不过只是win32平台,移植到android上还得自己去下载iconv库编译。
2. 把字符串写到xml文件中,然后解析xml文件,格式按照android中的strings.xml
这是一种更好的做法,特别是需要提供国际化支持时。
下面来看具体的实现:
1. 使用iconv库
iconv的作用是将文本在多种国际编码格式之间进行转换。
(1) 首先包含iconv.h头文件,c++->常规->附加包含目录:cocos2dx\platform\third_party\win32\iconv,如图:

(2) 创建头文件IconvString.h,源码:

1
2
3
4
5
6
7
8
#ifndef ICONV_STRING_H
#define ICONV_STRING_H
  
int  convert( char  *from_charset,  char  *to_charset,  char  *inbuf,  size_t  inlen,  char  *outbuf, size_t outlen);
  
int  gbk2utf8( char  *inbuf,  size_t  inlen,  char  *outbuf, size_t  outlen);
  
#endif

(3) 创建源文件IconvString.cpp,源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string>
#include "iconv.h"
  
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) 
// 编译链接的时候指定静态库
#pragma comment(lib,"libiconv.lib") 
#endif
  
int  convert( char  *from_charset,  char  *to_charset,  char  *inbuf,  size_t  inlen,  char  *outbuf, size_t outlen)
{
     iconv_t iconvH;
     iconvH = iconv_open(to_charset, from_charset);
     if ( !iconvH ) return  NULL;
     memset (outbuf, 0, outlen);
  
  #if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
     const char  *temp = inbuf;
     const char  **pin = &temp;
     char **pout = &outbuf;
     if ( !iconv(iconvH, pin, &inlen, pout, &outlen) )
     {
         iconv_close(iconvH);
         return NULL;
     }
#else
     if ( !iconv(iconvH, &inbuf, &inlen, &outbuf, &outlen) )
     {
         iconv_close(iconvH);
         return NULL;
     }
#endif
     iconv_close(iconvH);
     return NULL;
}
  
int  gbk2utf8( char  *inbuf,  size_t  inlen,  char  *outbuf, size_t  outlen)
{
     return convert( "gb2312" , "utf-8" , inbuf, inlen, outbuf, outlen);
}

代码比较简单,需要注意的是win32和android对应的iconv函数参数不一样。在win32平台需要指定lib库,它是iconv.h头文件对应的源码实现。android平台需要下载iconv库,编译的时候在iconv库的根目录下创建一个Android.mk文件就行,Android.mk内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
LOCAL_PATH:= $(call my- dir )
#libiconv.so
include $(CLEAR_VARS)
LOCAL_MODULE := libiconv
LOCAL_CFLAGS := \
   -Wno-multichar \
   -DAndroid \
   -DLIBDIR= "c" \
   -DBUILDING_LIBICONV \
   -DIN_LIBRARY
  
LOCAL_SRC_FILES := \
   libcharset /lib/localcharset .c \
   lib /iconv .c \
   lib /relocatable .c
  
LOCAL_C_INCLUDES += \
   $(LOCAL_PATH) /include \
   $(LOCAL_PATH) /libcharset \
   $(LOCAL_PATH) /lib \
   $(LOCAL_PATH) /libcharset/include \
   $(LOCAL_PATH) /srclib
include $(BUILD_STATIC_LIBRARY)

(4) 下面来看看如何使用,源码:

1
2
3
4
5
6
7
8
9
char  *inBuf =  "iconv: 你好,Alex Zhou" ;
size_t inLen =  strlen (inBuf);
size_t outLen = inLen << 1;
char  *outBuf = ( char  *) malloc (outLen);
gbk2utf8(inBuf, inLen, outBuf, outLen); 
  
CCLabelTTF* pLabel = CCLabelTTF::create(outBuf, "Arial" , 30);
pLabel->setColor(ccBLACK);
free (outBuf);

要注意转码前后的字符串占的空间是不一样的, 需要知道每种编码格式字符占的字节数:我的vs选择的是Unicode字符集,所以中文字符占2个字节,英文字符占1个字节;gb2312每个字符占2个字节,而UTF-8中文字符占3个字节,英文字符占1个字节。所以这里把存储输出的字符串的数组容量扩大了一部。
效果图:

2. 使用xml的方式
这里使用了引擎提供的CCSAXParser来解析xml,它内部是用libxml2来实现的。
(1) 创建XmlParser.h文件,源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef XML_PARSE_H
#define XML_PARSE_H
  
#include <string>
#include "cocos2d.h"
  
class XMLParser :  public cocos2d::CCObject,  public cocos2d::CCSAXDelegator
{
public :
     static XMLParser* parseWithFile( const char  *xmlFileName);
  
     static XMLParser* parseWithString( const char  *content);
  
     XMLParser();
     virtual ~XMLParser();
  
     // 从本地xml文件读取
     bool initWithFile( const char  *xmlFileName);
  
     // 从字符中读取,可用于读取网络中的xml数据
     bool initWithString( const char  *content);
  
     /**
     *对应xml标签开始,如:<string name="alex">, name为string,atts为string的属性,如["name","alex"]
     */
     virtual void  startElement( void *ctx,  const  char  *name,  const char  **atts);
  
     /**
     *对应xml标签结束,如:</string>
     */
     virtual void  endElement( void *ctx,  const  char  *name);
  
     /**
     *对应xml标签文本,如:<string name="alex">Alex Zhou</string>的Alex Zhou
     */
     virtual void  textHandler( void *ctx,  const  char  *s,  int len);
  
     cocos2d::CCString* getString( const char  *key);
  
private :
     cocos2d::CCDictionary *m_pDictionary;
     std::string m_key;
  
     std::string startXMLElement;
     std::string endXMLElement;
  
};
  
#endif

代码里已对主要的函数进行了解释,这里就不啰嗦了。
(2) 创建XmlParser.cpp,源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "XMLParser.h"
  
using namespace  std;
using namespace  cocos2d;
  
// 空格
const static  int SPACE = 32;
// 换行
const static  int NEXTLINE = 10;
// tab 横向制表符
const static  int TAB = 9;
  
XMLParser* XMLParser::parseWithFile( const char  *xmlFileName)
{
     XMLParser *pXMLParser = new  XMLParser();
     if ( pXMLParser->initWithFile(xmlFileName) )
     {
         pXMLParser->autorelease();   
         return pXMLParser;
     }
     CC_SAFE_DELETE(pXMLParser);
     return NULL;
}
  
bool XMLParser::initWithFile( const char  *xmlFileName)
{
     m_pDictionary = new  CCDictionary();
     CCSAXParser _parser;
     _parser.setDelegator( this );
     const char  *fullPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(xmlFileName);
     return _parser.parse(fullPath);
}
  
XMLParser* XMLParser::parseWithString( const char  *content)
{
     XMLParser *pXMLParser = new  XMLParser();
     if ( pXMLParser->initWithString(content) )
     {
         pXMLParser->autorelease();   
         return pXMLParser;
     }
     CC_SAFE_DELETE(pXMLParser);
     return NULL;
}
  
bool XMLParser::initWithString( const char  *content)
{
     m_pDictionary = new  CCDictionary();
     CCSAXParser _parse;
     _parse.setDelegator( this );
     return _parse.parse(content,  strlen (content) );
}
  
void XMLParser::startElement( void *ctx,  const  char  *name,  const char  **atts)
{
     this ->startXMLElement = ( char *)name;
     CCLog( "start=%s" , startXMLElement.c_str());
     if ( this ->startXMLElement == "string" )
     {
         while (atts && *atts)
         {
             const char  *attsKey = *atts;    
             if (0 == strcmp (attsKey, "name" ))
             {
                 ++ atts;
                 const char  *attsValue = *atts;
                 m_key = attsValue;
                 break ;
             }
             ++ atts;
         }
  
     }
  
}
  
void XMLParser::endElement( void *ctx,  const  char  *name)
{
     this ->endXMLElement = ( char *)name;
     CCLog( "end=%s" , endXMLElement.c_str());
}
  
void XMLParser::textHandler( void *ctx,  const  char  *s,  int len)
{
     string value(( char *)s, 0, len);
     //是否全是非正常字符
     bool noValue =  true ;
     for ( int i = 0; i < len; ++i)
     {
         if (s[i] != SPACE && s[i] != NEXTLINE && s[i] != TAB)
         {
             noValue = false ;    
             break ;
         }
     }
     if (noValue) return ;
     CCString *pString = CCString::create(value);
     CCLog( "key=%s value=%s" , m_key.c_str(), pString->getCString());
     this ->m_pDictionary->setObject(pString, this ->m_key);
}
  
CCString* XMLParser::getString( const char  *key)
{
     string strKey(key);
     return (CCString *) this ->m_pDictionary->objectForKey(strKey);
}
  
XMLParser::XMLParser()
{
}
  
XMLParser::~XMLParser()
{
     CC_SAFE_DELETE( this ->m_pDictionary);
}

如xml部分内容为:

1
< string name = "a" >b</ string >

上面的代码的作用是把key=a,value=b存储到字典中。
(3)下面来看看如何使用XmlParser,源码:

1
2
3
4
5
6
XMLParser *pXmlParser = XMLParser::parseWithFile( "strings.xml" );
CCString *pValue1 = pXmlParser->getString( "hello" );
CCString *pValue2 = pXmlParser->getString( "name" );
CCString *pValue = CCString::createWithFormat( "%s%s%s%s" , "XML: " , pValue1->getCString(), "," , pValue2->getCString());
CCLabelTTF* pLabel = CCLabelTTF::create(pValue->getCString(), "Arial" , 30);
pLabel->setColor(ccBLACK);

strings.xml的内容:

1
2
3
4
5
<? xml version = "1.0" encoding = "utf-8" ?>
< resources >
     < string name = "hello" >你好</ string >
     < string name = "name" >Alex Zhou</ string >
</ resources >

效果如图:

ok,到这里就结束了,android对应的iconv库我已经打包到源码中了。
源码:http://download.youkuaiyun.com/detail/zhoujianghai/5031137

 

2013年8月11号更新:
有朋友反馈说在xml中的换行符(“\n”)不起作用,原因是XMLParser解析xml时,把”\n”变成了”\\n”,这样就会把换行符原样输出了,解决方法很简单,直接把”\\n”替换成”\n”就可以了,添加一个字符串替换函数。原理:遍历原字符串,查找要替换的字符串在原字符串中的位置pos,然后截取从i到pos的子字符串再跟新字符串拼接,然后更新i,继续查找。在XmlParser.cpp中添加下面的字符串替换函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
string replace(string source, string pattern, string dstPattern)
{
     string result;
     string::size_type pos;
  
     int lenSource = source.length();
     int i = 0;
  
     for (i = 0; i < lenSource; ++i)
     {
         pos = source.find(pattern, i);
         if (string::npos == pos)
             break ;
  
         if (pos < lenSource)
         {
             string s = source.substr(i, pos - i);
             result += s;
             result += dstPattern;
             i = pos + pattern.length() - 1;
         }
     }
     result += source.substr(i);
     return result;
}

修改XmlParser.cpp的textHandler函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void  XMLParser::textHandler( void  *ctx,  const  char  *s,  int len)
{
     if ( this ->m_key.length() == 0)
         return ;
  
     string value(( char *)s, 0, len);
     CCLog( "s=%s, len=%d" , value.c_str(), value.length());
     //是否全是非正常字符
     bool noValue =  true ;
  
     for ( int i = 0; i < value.length(); ++i)
     {
         char c = value.at(i);
         CCLog( "v=%d" , c);
  
         if (c != SPACE && c != NEXTLINE && c != TAB)
         {
             noValue = false ;    
             break ;
         }
     }
     if (noValue) return ;
     string result = replace(value, string( "\\n" ), string( "\n" ));
     CCString *pString = CCString::create(result);
     CCLog( "key=%s value=%s" , m_key.c_str(), pString->getCString());
     this ->m_pDictionary->setObject(pString, this ->m_key);
}

更新strings.xml:

1
2
3
4
5
<? xml version = "1.0" encoding = "utf-8" ?>
< resources >
     < string name = "hello" >你好世界\n</ string >
     < string name = "name" >Alex Zhou</ string >
</ resources >

运行效果如下图:

cocos2dx2.1.4解决win32中文乱码编译自vs2012 原来的代码链接:http://download.youkuaiyun.com/detail/aa4790139/4694562 此代码在cocos2dx2.1.4下面编译有部分错误,我修改后,正常。 下下来后,请在VC++包含目录中链接(F:\cocos2d-x-2.1.4\cocos2dx\platform\win32;F:\cocos2d-x-2.1.4\cocos2dx\platform\third_party\win32\OGLES\GL\;F:\cocos2d-x-2.1.4\cocos2dx\platform\third_party\win32\OGLES;F:\cocos2d-x-2.1.4\cocos2dx\platform\third_party\win32;F:\cocos2d-x-2.1.4\cocos2dx\platform;F:\cocos2d-x-2.1.4\cocos2dx\include;F:\cocos2d-x-2.1.4\cocos2dx\kazmath\include\kazmath;F:\cocos2d-x-2.1.4\cocos2dx\kazmath\include;F:\cocos2d-x-2.1.4\cocos2dx\kazmath;F:\cocos2d-x-2.1.4\cocos2dx;F:\cocos2d-x-2.1.4\external\Box2D;F:\cocos2d-x-2.1.4\external;F:\cocos2d-x-2.1.4;F:\cocos2d-x-2.1.4\CocosDenshion\include;F:\cocos2d-x-2.1.4\CocosDenshion; )或者是自行更改相对路径。然后在链接器里附加包含目录加( F:\cocos2d-x-2.1.4\Debug.win32)以免出现libcocos2dx找不到的错误。 立即下载

相关推荐

win32环境下cocos2d-x转码显示中文

win32环境下 cocos2d-x 转码显示中文汉字

cocos2d-x 显示中文字符和解析XML文件 转载

源地址:http://codingnow.cn/cocos2d-x/1038.html 在cocos2d-x中直接显示中文的时候会出现乱码,虽然在实际开发中把字符串直接写在代码里也不是好的做法,但是有时候也是为了更方便了。本文采用两种方案来解决这个问题:1. 使用iconv,引擎也提供了这个库,不过只是win32平台,移植到android上还得自己去下载iconv库编译。2. 把字符串写到xml...

weixin_33929309的博客 241

亲试过可以通过cygwin编译发布cocos2d-x几种中文乱码解决方案

现在的网络情况就是N个网站同一个资源搜来搜去,让人越发焦虑。此文档也是我从几天焦虑中发现可以用的几种解决cocos2d-x中文乱码的方法。亲自试过了。cygwin可以编译过。但是我感觉直接在代码里面写宽字符=L("中文") 似乎不行。自己编译那个iconv好像也难,用jni回调后java转码似乎又违背了跨平台的真正含义。还有好多未知的系统接口调用,如果都这样干,那不如直接实现得了。

Cocos2dx 中文乱码的解决方法

问题与解决方法 在windows环境下使用visual studio 开发cocos2d-x,由于visual studio 默认编码为GBK 格式,而cocos2d-x引擎默认编码为UTF-8, 如果有用到中文,在游戏运行时有可能会出现乱码的情况,这个问题一般有三种解决方案,如下 1、将源码文件保存为utf-8格式(不建议,治标不治本) 2、自己编写编码转换代码,或者使用Cocos2dx的

星宇的专栏 3656

AI开发助手介绍

AI开发助手介绍随着NLP方向发展越来越成熟,AI写代码领域出现了几个非常好的模型,今天笔者给大家推荐几个AI Coding 助手AI Coding助手是以IDEA插件或vim插件形式提供服务,在编辑器中写代码时,可以实时预测下一行要输入的代码,提升开发效率。Github Copilot首先要介绍的是Github Copilot,Copilot是个AI Coding助手,它从注释和代码中提取上下文,给出单行和整个函数的代码建议,Copilot由Open AI 的CodeX模型提供支持,它是一个由OpenAI

bobo_simpler的博客 5765

基于Q-learning的无人机三维路径规划(含完整C++代码)

基于Q-learning的无人机三维路径规划(含完整C++代码)

weixin_54186646的博客 1万+

【Cocos2d-x游戏开发】解决Cocos2d-x中文乱码的三种方法

众所周知,Cocos2d-x是一款不错的开源引擎,但是在Cocos2d-x中直接使用中文是无法正确显示的。 解决这个问题常用的有三种方法: 1.通过转换为UTF-8编码来显示。 2.使用iconv库来解决。 3。使用解析xml或者json文件来解决。 这里推荐使用第三种方法来解决,因为比较简单方便,还能支持I18N国际化。下面我们来一一详细了解一下每种解决方案的具体实现: 1、

lianghui0811 557

三相直流无刷电机(带HALL传感器)BLDC控制一

本案例选择TIM0的CH0/CH1/CH2三个通道接入三路原始hall输出信号。三路TIM_CHx(48)通过配置存入到NIP寄存器(new input pattern,3 bits)内。未完待续。

m0_69929716的博客 405

cocos2d-x解决中文乱码问题的几种办法

 cocos2d-x解决中文乱码问题的几种办法 昨天改写cocos2d-x的例程,想在其基础上加上一个计分系统。 没有分数实在让人没有玩下去的动力! 我在主场景上加上了一个CCLabelTTF,用于显示分数。 但是意外的发现,当内容含有中文时,CCLabelTTF的显示内容为乱码。 无奈只好Google百度寻求答案,明白了这个问题的缘由。 因为coco

水上漂的专栏 3835

Android流畅度优化实战:从掉帧定位到布局与渲染调优

在移动应用开发中,性能优化是决定用户体验与留存率的关键环节,其中Android流畅度优化更是核心命题。用户感知的“卡顿”往往并非持续低帧率,而是由于掉帧率波动引发的偶发不流畅。本文从性能优化理论出发,系统讲解如何使用Systrace、CPU Profiler等工具定位掉帧瓶颈,深入分析布局层级过深、过度绘制、对象分配与GC压力等常见诱因。同时结合冷启动耗时、列表滚动掉帧、Bitmap加载等真实工程案例,阐述从应用层到系统层的分级优化策略,并给出低端机适配、异步化改造及线上监控体系搭建的实践方案。内容覆盖布局

weixin_29185493的博客 200

INMP441麦克风与ESP32的I2S音频采集实战指南

本文提供了INMP441数字麦克风与ESP32开发板通过I2S接口进行高质量音频采集的完整实战指南。详细讲解了硬件连接、软件配置、数据读取及基础处理,并分享了常见的避坑技巧与性能优化建议,帮助开发者快速构建物联网音频应用。

weixin_28396629的博客 598

cocos2d-x解决中文乱码

一 介绍 最近由于各种各样的原因,好长时间没有学习cocos2d-x了。突然有种害怕的感觉,这样下去,以前学的关于cocos2d-x的一点皮毛会彻底忘记的,下次再学,估计又得重头开始了。所以,还是要平时多多使用吧,持之以恒最重要了... 由于在cocos2d-x中直接使用中文会出现乱码,谁让cocos2d-x是由cocos2d而来,而cocos2d这东西是老外写的呢?通常解决中文乱码有

qq51931373的专栏 768

解析vCard 3.0:提取电子名片中的姓名

N:LastName;FirstName;;;END:VCARD和END:VCARD标记数据块的开始和结束。N字段存储结构化姓名(分号分隔)。FN字段为直接可读的显示名称。其他字段如TELEMAIL等保存联系信息。

qq_45797625的博客 2777

cocos2dx java 乱码_[cocos2d-x] --- 完美解决中文乱码

该楼层疑似违规已被系统折叠隐藏此楼查看此楼一 介绍最近由于各种各样的原因,好长时间没有学习cocos2d-x了。突然有种害怕的感觉,这样下去,以前学的关于cocos2d-x的一点皮毛会彻底忘记的,下次再学,估计又得重头开始了。所以,还是要平时多多使用吧,持之以恒最重要了...由于在cocos2d-x中直接使用中文会出现乱码,谁让cocos2d-x是由cocos2d而来,而cocos2d这东西是老...

weixin_42533622的博客 156

华为OD面试八股真题 - 操作系统 - 1

华为OD技术面,操作系统相关八股真题提供详细解答,这篇博客主要涉及于进程和线程相关知识点

qq_45776114的博客 1633

LFM线性调频信号的MATLAB仿真

线性调频(LFM)是一种不需要伪随机编码序列的扩展频谱调制技术。由于线性调频信号占用的频带宽度远大于信息带宽,所以也可以获得很大的系统处理增益。线性调频信号又称鸟声(Chirp)信号,因为其频谱带宽落于可听范围,则听若鸟声,所以又称Chirp扩展频谱(CSS)技术。LFM技术在雷达、声纳技术中有广泛应用,如在雷达定位技术中,它可在增大射频脉冲宽度、提高平均发射功率、加大通信距离同时又保持足够的信号频谱宽度,不降低雷达的距离分辨率。线性调频(LFM)是一种不需要伪随机编码序列的扩展频谱调制技术。

平时工作较为繁忙,私信消息一般晚上回复,谢谢大家~~ 902

cocos2d-x 3.4 中文乱码解决之道

cocos2dx 中文乱码解决之道 须要引入五个文件 1、iconv.h 2、iconvString.cpp 3、iconvString.h 4、iconv.dll 5、libiconv.lib 完整下载地址http://download.youkuaiyun.com/detail/dao_1990/8935089 iconv.h /* Copyright (C...

aoe41606的博客 126

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

[cocos2d-x] --- 完美解决中文乱码

http://blog.youkuaiyun.com/cen616899547/article/details/9110483 一 介绍 最近由于各种各样的原因,好长时间没有学习cocos2d-x了。突然有种害怕的感觉,这样下去,以前学的关于cocos2d-x的一点皮毛会彻底忘记的,下次再学,估计又得重头开始了。所以,还是要平时多多使用吧,持之以恒最重要了...

灵思致远Leansmall的博客 899

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: Android横竖屏切换总结
下一篇: cocos2dx背景音乐
mincheat
博客等级 码龄17年 46粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值