这几天做了一个对Excel进行对比操作的一个小项目,凑了点学费:)。主要涉及到的功能就是先用QT做一个简单的界面,可供选择输入为文件或文件夹,选择完成之后对输入文件的格式进行检查,然后对比已有的数据库中(很多个文件,大概一共十几万行数据)的数据,分析输入文件中数据的错误,最后将分析后的结果写到Excel文件中,在这个项目主要涉及到以下几个知识点:

1. QT中文乱码的解决

QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。
“我是中文”这样写的时候,它是传统的 char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。而问题一般都出在很多用户对自己当前的编码没太多概念。

在这里介绍一篇对字符编码讲解的很透彻的一篇文章:ASCII、Unicode、GBK和UTF-8字符编码的区别联系

QString的内部是使用的unicode编码,所以本质就是将所有字符转换成unicode编码即可正常显示。

所以当使用这样的代码:

1
QString a = "我是中文"

其实等价于

1
2
const char* s = "我是中文"
QString a = s;

那么当需要从窄字符串char转成Unicode的QString字符串时,你需要告诉Qt你的这个char 是什么编码?GBK、BIG5、Latin-1.

所以关于Qt的中文乱码,Qt4和Qt5有不同的解决方案。
在Qt4中,常用的解决方案是在main.cpp加这几行代码

1
2
3
4
QTextCodec *codec = QTextCodec::codecForName("system");//获取系统中文编码
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);

这几行代码就是告诉程序你的char* 中到底使用的是什么编码。

而在Qt5中取消了这几个函数,取而代之的是另外的解决方案。
用QTextCodec类中的转换函数

1
2
3
4
5
6
7
8
9
10
11
std::string utf82gbk(const QString &inStr)
{

QTextCodec *gbk = QTextCodec::codecForName("GB18030");
return gbk->fromUnicode(inStr).data();
}

QString gbk2utf8(const std::string &inStr)
{

QTextCodec *gbk = QTextCodec::codecForName("GB18030");
return gbk->toUnicode(inStr.c_str());
}

Read more »

一直用的一个shadowsocks服务由于一些原因被停掉了,这对谷歌重度用户的我简直不能忍,就决定自己动手了,对比了下VPS提供商,推荐最多的就是linodedigitalocean了,linode是老牌主机商了,digitalocean是最近兴起的性价比超高的主机商,如果不差钱就买linode,追求性价比就买digitalocean。

由于我最近很差钱,所以digitalocean就是首选了,我选的是最低配的$5一个月的,首次购买点击这个链接注册可以送$10,相当于$5可以用三个月啊,相当划算。

点击注册成功之后,它会让你绑定信用卡或者paypal,绑定成功后就可以购买啦,如下图这样
然后点击Create Droplet,之后就看到类似这样

Read more »

在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分一下这几个概念。

1.全局字符串池(string pool也有叫做string literal pool)

全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(记住:string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。)。
在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(也就是我们常说的用双引号括起来的)的引用(而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。

2.class文件常量池(class constant pool)

我们都知道,class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)
字面量就是我们所说的常量概念,如文本字符串、被声明为final的常量值等。
符号引用是一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可(它与直接引用区分一下,直接引用一般是指向方法区的本地指针,相对偏移量或是一个能间接定位到目标的句柄)。一般包括下面三类常量:

  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符

常量池的每一项常量都是一个表,一共有如下表所示的11种各不相同的表结构数据,这每个表开始的第一位都是一个字节的标志位(取值1-12),代表当前这个常量属于哪种常量类型。

Read more »