C/C++语言对宽字符集的处理

我们接触C语言中的字符是从char开始的,但是众所周知,char类型是不支持中文的,于是那些先贤们把字符扩展为宽字符来表示一些非ANSI字符。 但是没有C语言标准支持的话,各个厂商又要开始各自为政,C语言的代码跨平台优势也就没有了,所以C99添加了对宽字符的支持。

C语言对宽字符的支持

wchar_t

对应与常见的char,宽字符版的char是wchar_t,wchar_t不是内置类型,而是定义在wchar.h文件中的。

有了wchar_t,我们可以在程序中存储宽字符了。

另外,wchar.h中定义了一个极为有用的宏L,它用来存储wchar_t常量。举例如下:

L”鲁”,L’鲁’ 分别表示的是字符串鲁和宽字符鲁。至于”鲁”,则在不同的平台下有不同的程序内表示方法,不跨平台。

wscanf, wprintf

能存储宽字符后,我们还得输入输出宽字符,所以wscanf, wprintf, wgets 等等函数都出现了,他们都是对应函数的宽字符版。

wscanf和wprintf的第一个参数是指向wchar_t的指针,为格式化字符串。


给Eclipse添加pkg-config支持

原来用gedit+gcc来编写GTK程序(主要是学习例程),后来随着代码越写越多,需要一个IDE来辅助开发,于是想到了万能的Eclipse。 可是Eclipse可以支持C语言开发,却不支持pkg-config命令集成。搞得每次新建GTK工程都要把pkgconfig的输出改到Eclipse中。 后来烦了,自己google之,得解:http://marketplace.eclipse.org/content/pkg-config-support-eclipse-cdt

安装Eclipse

首先,安装jre和jdk等依赖。 接下来下载Eclipse。我原来下载了Eclipse 4.3 Classic ,但是最新版成了Eclipse 4.3 Standard ,都是可以的。 然后解压Eclipse。(双击eclipse文件即可运行Eclipse) 另外,Eclipse CDT和gtk开发的其他依赖包也要安装。

安装Eclipse Marketpalce Client(MPC)

我下载的是Eclipse 4.3 Classic,所以需要安装MPC;如果你下载的是Eclipse 4.3 Standard,可以跳过此步。 在Install New Software窗口中选上所有网站,然后搜索market即可看到MPC;点击下一步,然后同意许可协议等。 安装完成后重启Eclipse即可完成MPC的安装。

在market中安装Pkg-config support

在帮助菜单中打开Eclipse Marketpalce: 1 搜索pkg-config,如图: 2 点击安装,一直确认、同意许可协议。

Pkg-config support的使用

首先,创建一个Hello World C工程,贴入GTK程序代码(代码附后),此时Eclipse提示程序中有好几处错误/警告: 3 接下来,打开项目的设置菜单 -> C/C++ Build -> Settings -> Pkg-config 选项卡: 4 在其中的选项中勾选 GTK+-2.0 (我个人使用的是GTK 2.0,可根据自己的情况酌情选择): 5 然后点击确定。 稍等几秒后就会发现Eclipse识别出来了头文件包含、GTK类型定义等,如图: 6 点击运行(Run),可以看到GTK程序在Eclipse中正常运行: 7 GTK测试代码

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


unzip的中文问题

唉,unzip的-O选项一直是一个传说中的存在,而且unzip的开发者一直没有意向修复。 故自己动手,丰衣足食,用python写了一个MultiCharset ZIP,代码附上:

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
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import zipfile
from optparse import OptionParser

def listZip(zipf):
    print "Archive:  %s" %zipf
    print "  Length      Date    Time    Name"
    print "---------  ---------- -----   ----"
    filist=zipfile.ZipFile(zipf).infolist()
    totalnum=0
    totalsize=0
    for finfo in filist:
        totalnum+=1
        totalsize+=finfo.file_size
        print "%9d " %finfo.file_size ,
        print "%04d-%02d-%02d" %(finfo.date_time[0],finfo.date_time[1],finfo.date_time[2]),
        print "%02d:%02d  " %(finfo.date_time[3],finfo.date_time[4]),
        print finfo.filename.decode('gb18030').encode('utf-8')
    print "---------                     -------"
    print "%9d" %totalsize ,
    print "                   ",
    print "%d files" %totalnum

def exZip(zipf,exdir):
    zf=zipfile.ZipFile(zipf)
    nlist=zf.namelist()
    nlist.sort(key=lambda x:len(x))
    for fn in nlist:
        fnew=unicode(fn,'gb2312').encode('utf8')
        if fnew.endswith('/'):
            os.mkdir(exdir+fnew)
        else:
            file(exdir+fnew,'wb').write(zf.read(fn))
        print fnew
    zf.close()

def main():
    usage = "usage: "+sys.argv[0]+" [options] zipfile1 zipfile2"
    parser = OptionParser(usage=usage)
    parser.add_option("-l","--list",action="store_true",help="list files in zip file",dest="islist",default=True)
    parser.add_option("-x","--extract",action="store_true",help="extract zip files",dest="isex",default=False)
    parser.add_option("-d","--exdir",action="store",help="define extract directory",dest="exdir",default=".")
    #parser.add_option("-z","--exdir",action="store",dest="exidr")

    (options,args)=parser.parse_args();

    if(options.isex):
        for zf in args:
            exZip(zf,options.exdir+"/")
    else:
        if(options.islist):
            for zf in args:
                listZip(zf)

if __name__ == "__main__":
    main()

可以在~/bin/目录下创建一个mczip文件,写入代码,添加可执行权限,即可在终端中用mczip来列出zip文件内容、解压zip文件。

用法:

1
2
3
4
5
6
Usage:mczip.py [options] zipfile1 zipfile2
Options:
-h, --help            show this help message and exit
-l, --list            list files in zip file
-x, --extract         extract zip files
-d EXDIR, --exdir=EXDIR     define extract directory`

只有列出zip包的文件内容和解压zip文件两个功能,只能处理gb18030编码。

注:Python3的zip模块判断更加奇葩了,只要文件名不是ascii编码,就认为是utf8编码,而且不保留bytes格式的文件名,有点难办啊。


gcc的使用和编译时的符号确定

一般来说,我们编译c语言程序要经过编译(预处理)、和链接两步。当然教材上讲的时候还有预处理。 预处理

1
gcc -E code.c -o code.e.c

预处理主要处理文件包含和宏定义等等。 编译

1
gcc -c code.c -o code.o

编译主要把c语句翻译成二进制代码(一般此步骤包括了预处理)。 但是有一些函数的实现没有在预处理过的c语言文件中,类似的还有extern声明的变量,所以现在编译的文件还没有办法执行。这些无法决定位置的函数和变量,在.o文件中统称为未定义的符号。 链接

1
gcc code.o -o code

在这一步我们要把所有.o文件中的未定义符号给确定下来,确定的来源有两种,查看其他.o文件的导出表中查找,从其他.so(dll)文件的导出表中查找。 gcc还有一个重要的参数是-g,表示编译的时候保留调试信息(包括c语句和汇编语句的对应关系,变量的分配) gcc的-o参数指定输出文件的名字。 让我们通过一个例子来了解这个流程

test.c
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

extern int a;

extern void test();

int main()
{
test();
return 0;
}

先预处理它:

1
gcc -E test.c -o test.e.c

fedora 18 安装配置


安装fastestmirror:

个人不推荐更改repo文件,因为有单点依赖

yum install yum-plugin-fastestmirror

安装rpmfusion源:

RPM Fusion is a merger of Dribble, Freshrpms, and Livna.

yum localinstall –nogpgcheck http://mirrors.163.com/rpmfusion/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://mirrors.163.com/rpmfusion/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

字体:

yum install wqy-bitmap-fonts wqy-zenhei-fonts wqy-unibit-fonts wqy-microhei-fonts
yum install cjkuni-uming-fonts cjkuni-ukai-fonts

gedit乱码:


Linux下HaoZip创建的分卷文件的解压缩

近来看mysql视频,下载下来是“X.haozip01.zip”这样的文件,无法解压。 经过数次探索后,发现直接把文件拼装在一起再用unzip解压即可。 如下:

cat X.haozip01.zip X.haozip02.zip > X.zip
unzip X.zip


用reveal.js+markdown制作树型结构的slides

reveal.js 可以让你制作出基于网页的slides,轻量级,跨平台,非私有格式。 说来惭愧,我做的大多slides都是想表达这样的结构: image1 于是,就做出了这样的slides: image2 我们姑且称这样的slides为“树型结构slides”。我们要用 reveal.js来制作这样的 slides 。 fork项目:

git clone git://github.com/hakimel/reveal.js.git

然后修改index.html文件,把class为slides的div元素换为如下div元素(覆盖掉原来的div元素及其子孙元素)

data-separator=”^\n\n\n”表示用三个连续的换行作为横向分隔符(即顶层slide之间的分隔),data-vertical=”^\n\n”表示用两个个连续的换行作为纵向分隔符(即第二层slide之间的分隔)。 举例如下:

使用方法:首先展示开始页,按右或者回车显示下一页,按左显示上一页,按上下显示相应页面子页面。Esc显示概览。 如图: image3 不足:

需要slides作者有html/css基础。

加载时需要下载网页字体(这个可以先用离线模式解决,日后联系开发者解决)

只适用于“扁平”状的slides,如果层数太多,展示效果不好。


建立xdebug+eclipse的调试环境

几周了,终于让 eclipse 能够调试php代码了,期间找了许多资料,但是总不能如愿,于是记录如下。

安装xdebug

fedora 下直接安装 php-pecl-xdebug 包就算是配置好了 php 的 xdebug 扩展。

记得systemctl reload httpd.service 访问 phpinfo 页面时应该有 xdebug 的相关信息:

Screenshot from 2013-04-03 16:01:51

然后打开 display_errors ,即 php.ini 里面有 display_errors= On ,那么打开一个有异常的页面会出现彩色提示。

Screenshot from 2013-04-03 15:51:52

配置远程调试

这时可以配置远程调试。在 /etc/php.d/xdebug.ini 中写入如下几行:

1
2
3
4
5
[Xdebug]
xdebug.remote_autostart=On
xdebug.remote_enable=On
xdebug.remote_host=127.0.0.1
xdebug.remote_handler=dbgp

Linux 下 Eclipse 的外观修改(图标大小)

在Linux(F18+gnome3)下用Eclipse最显著的一个特点是图标特别的“大气”,菜单栏都到两行了,就是图标特别的大。给张图就明白了:

before

今天突然有改了它的冲动,百度之,曰为gtk2的风格问题。不过,百度出来的答案都没用,于是google,得之:

https://www.davidandrzejewski.com/2012/08/03/make-eclipse-less-ugly-in-linux-mint/

文中的配置有一点不妥,引用如下:

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
style "compact"
{
GtkButton::default_border={0,0,0,0}
GtkButton::default_outside_border={0,0,0,0}
GtkButtonBox::child_min_width=0
GtkButtonBox::child_min_heigth=0
GtkButtonBox::child_internal_pad_x=0
GtkButtonBox::child_internal_pad_y=0
GtkMenu::vertical-padding=1
GtkMenuBar::internal_padding=1
GtkMenuItem::horizontal_padding=4
GtkToolbar::internal-padding=1
GtkToolbar::space-size=1
GtkOptionMenu::indicator_size=0
GtkOptionMenu::indicator_spacing=0
GtkPaned::handle_size=4
GtkRange::trough_border=0
GtkRange::stepper_spacing=0
GtkScale::value_spacing=0
GtkScrolledWindow::scrollbar_spacing=0
GtkExpander::expander_size=10
GtkExpander::expander_spacing=0
GtkTreeView::vertical-separator=0
GtkTreeView::horizontal-separator=0
GtkTreeView::expander-size=12
GtkTreeView::fixed-height-mode=TRUE
GtkWidget::focus_padding=0
font_name="Liberation Sans,Sans Regular 8"
text[SELECTED] = @selected_text_color
}
class "GtkWidget" style "compact"
style "compact2"
{
xthickness=1
ythickness=1
}

class "GtkButton" style "compact2"
class "GtkToolbar" style "compact2"
class "GtkPaned" style "compact2"

第30行使tweak丧失了对程序字体的控制权,有越俎代庖之嫌,删去。
第5行个人觉得边框太小,故改为1 。
最终解决方案:

~/gtkrc-2.0文件中添加如下语句:

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
style "compact"
{
GtkButton::default_border={1,1,1,1}
GtkButton::default_outside_border={0,0,0,0}
GtkButtonBox::child_min_width=0
GtkButtonBox::child_min_heigth=0
GtkButtonBox::child_internal_pad_x=0
GtkButtonBox::child_internal_pad_y=0
GtkMenu::vertical-padding=1
GtkMenuBar::internal_padding=1
GtkMenuItem::horizontal_padding=4
GtkToolbar::internal-padding=1
GtkToolbar::space-size=1
GtkOptionMenu::indicator_size=0
GtkOptionMenu::indicator_spacing=0
GtkPaned::handle_size=4
GtkRange::trough_border=0
GtkRange::stepper_spacing=0
GtkScale::value_spacing=0
GtkScrolledWindow::scrollbar_spacing=0
GtkExpander::expander_size=10
GtkExpander::expander_spacing=0
GtkTreeView::vertical-separator=0
GtkTreeView::horizontal-separator=0
GtkTreeView::expander-size=12
GtkTreeView::fixed-height-mode=TRUE
GtkWidget::focus_padding=0
}
class "GtkWidget" style "compact"
style "compact2"
{
xthickness=1
ythickness=1
}
class "GtkButton" style "compact2"
class "GtkToolbar" style "compact2"
class "GtkPaned" style "compact2"

效果:


ProFTPD限制FTP模式

以前搞过ProFTPD禁止主动模式,但是这两天有这个需求的时候却忘记了,看来得写一日志记录下。

首先,环境是 fedora 17 + proftp 。

默认的配置是主动模式和被动模式都可用。

主动模式下访问记录:

1
2
3
4
Command:   
PORT 127,0,0,1,237,87
Response:    200
PORT command successful

被动模式访问记录:

1
2
Command:    PASV
Response:    227 Entering Passive Mode (127,0,0,1,157,107).

如果需要禁止主动模式访问,则只需要在/etc/proftd.conf<Global>段中添加如下三行:

1
2
3
<Limit PORT>
DenyAll
</Limit>

即禁止PORT指令,则主动模式访问记录变为:


Robert Lu

关注我的公众号