帐前卒专栏

code, software architect, articles and novels.
代码,软件架构,博客和小说

转至 sucn .com

研究好多天了,也试过好多办法了,总结出目前发现最好的方法:
先说一下基本的东西:
<%@ codepage=936%>简体中文
<%@ codepage=950%>繁体中文
<%@ codepage=65001%>UTF-8
codepage指定了IIS按什么编码读取传递过来的串串(表单提交,地址栏传递等)。

出乱码的原因也就是网站要整合的时候模块编码不一样引起的。
就像我的博客一样,整合的时候都会出这个问题,因为BLOG是Utf-8的,
近来很多网友都在为这个问题咨询,我尝试了很多种方法。
最方便的方法如下:
不要转换任何模块网页的编码该utf-8的还是utf-8,该Gb22312的还是Gb2312
在Utf-8模块的包文件(如conn.asp,但是要注意conn.asp必须是在第一行调用)最前面加上
<%@LANGUAGE=“VBSCRIPT” CODEPAGE=“65001”%>
<%Session.CodePage=65001%>
在GB2312模块的包文件最前面加上
<%@LANGUAGE=“VBSCRIPT” CODEPAGE=“936”%>
<%Session.CodePage=936%>
其他编码的类推。再出问题,我也帮你了了,我现在是都没问题了^^

JSP中文问题

一、JSP页面显示乱码二、表单提交中文时出现乱码三、数据库连
大家在JSP的开发过程中,经常出现中文乱码的问题,可能一至困扰着您,我现在把我在JSP开发中遇到的中文乱码的问题及解决办法写出来供大家参考。

一、JSP页面显示乱码
下面的显示页面(display.jsp)就出现乱码:

JSP的中文处理 <% out.print("JSP的中文处理"); %> 对不同的WEB服务器和不同的JDK版本,处理结果就不一样。原因:服务器使用的编码方式不同和浏览器对不同的字符显示结果不同而导致的。解决办法:在JSP页面中指 定编码方式(gb2312),即在页面的第一行加上:<%@ page contentType="text/html; charset=gb2312"%>,就可以消除乱码了。完整页面如下: <%@ page contentType="text/html; charset=gb2312"%> JSP的中文处理 <% out.print("JSP的中文处理"); %>

二、表单提交中文时出现乱码
下面是一个提交页面(submit.jsp),代码如下:

JSP的中文处理
下面是处理页面(process.jsp)代码: <%@ page contentType="text/html; charset=gb2312"%> JSP的中文处理 <%=request.getParameter("name")%> 如果submit.jsp提交英文字符能正确显示,如果提交中文时就会出现乱码。原因:浏览器默认使用UTF-8编码方式来发送请求,而UTF-8和GB2312编码 方式表示字符时不一样,这样就出现了不能识别字符。解决办法:通过request.setCharacterEncoding("gb2312")对请求进行统一编码 ,就实现了中文的正常显示。修改后的process.jsp代码如下: <%@ page contentType="text/html; charset=gb2312"%> <% request.seCharacterEncoding("gb2312"); %> JSP的中文处理 <%=request.getParameter("name")%>

三、数据库连接出现乱码
只要涉及中文的地方全部是乱码,解决办法:在数据库的数据库URL中加上useUnicode=true&characterEncoding=GBK就OK了。

四、数据库的显示乱码
在mysql4.1.0中,varchar类型,text类型就会出现中文乱码,对于varchar类型把它设为binary属性就可以解决中文问题,对于text类
型就要用一个编码转换类来处理,实现如下:
public class Convert {
/** 把ISO-8859-1码转换成GB2312
*/
public static String ISOtoGB(String iso){
String gb;
try{
if(iso.equals(“”) || iso == null){
return “”;
}
else{
iso = iso.trim();
gb = new String(iso.getBytes(“ISO-8859-1”),“GB2312”);
return gb;
}
}
catch(Exception e){
System.err.print(“编码转换错误:”+e.getMessage());
return “”;
}
}
}
把它编译成class,就可以调用Convert类的静态方法ISOtoGB()来转换编码。

没有想到自己竟然过了微软实习生的笔试和面试。 出乎过去的想像。本来是想不为学院丢脸就ok了。现在想想真的没有给学院丢脸。

上午进行的笔试,Tim Chen来的太晚了,本来说10点,结果快10点半才来。这半个小时里和老边闲聊了一阵。然后Tim就来了。先交了简历,然后自己简短的介绍
了下自己。自己写的简历最短,自己的介绍似乎也是最短的。说自己兴趣爱好的时候,我说自己喜欢写blog。Tim chen开玩笑的说:作家。我其实心里想,自己喜欢
看着blog的计数器慢慢增长。然后Tim让我们每人写篇英语短文介绍自己上午干了些什么。限时7分钟。具体用了多长时间我也保护太清楚,反正记得自己写了半页纸。然
后是最经典的atoi()函数编写,不过要写出测试用例。看来Tim真的是要招测试方面的人。限时大概15分钟。自我感觉良好,毕竟之前看过类似的题。最后一题:写一
个汉英字典类。自己想了想用两个类实现。一个类是字典,另外一个是单词。还剩下最后2分钟的时候,突然想起他要用一个类。于是马上改过。写了些数据成员,然后加了增删
查改和构造析构6个方法。还剩10秒。心里不想写了。算了,我反正想不起更多的方法了。

下午吃饱喝足想睡觉,可迟迟睡不着。Tim说下午打电话通知来面试。睡不着就起来洗个澡。结果还是没有电话来。心有些凉,感觉也不会录自己了,还不如去看看信息安全。
正想着,浩哥就打来电话找我面试。

下午面试自我感觉还算良好。没有说错什么,只是说了些自己的缺点和不足。并且很高兴的告诉tim今天学院推荐的五个人其中有4个曾是自己的组员。然后我们俩就聊起来X
P方法。后来Tim问是否有意向去微软。感觉怪怪的。为什么不说你被录取了。想不通。。。。最后Tim主动与我握手。感觉有些惭愧,没有主动和他握手。下次再见的时候
补上好了。
晚上有些兴奋,依然没有睡好觉。

由字符串转为int型…

int strToInt(const char * c)
{
if(c == NULL)
throw “NULL point…”;
int sum = 0;
int n = 10;
int flag = 1;
while(*c)
{
if(*c == ’ '||*c == ‘+’)
{
c++;
continue;
}
if(*c == ‘-’)
{
flag = -1;
c++;
continue;

}
sum *= n;
sum += c-‘0’;
c++;
}
return sum
flag;
}

sizeof()用于查看变量 所占的空间。例如:

sizeof(int) // 4

sizeof(float)// 4

sizeof(double)//8

sizeof(char) //1

char * p = new char[20];sizeof(p)//这里是p指针所占的空间故为4

char * p = “google”;sizeof(p);//这里是p指针指向字符串常量,但sizeof()的结果仍然为4

char *p [20];//这时sizeof()为80 = 20 × 4

char p[20];sizeof(p);//这里的结果为20 = 20 × 1

sizeof()使用了编译器生成的符号表的缘故。编译器的符号表类似于下面的形式,将所有的变量和其类型都记录在表中。

变量                  类型             大小

p                        char             10----------(数组)

a                        char              1

b                       double          8

d                       point              4

当要sizeof(变量)时,sizeof就会查取符号表。如果是单一类型的变量就会直接输出此类型变量的所占大小。并且也可以同时知道这个变量是否是数组。

但是Class类型稍稍有些不同,以下代码:

class A
{
public:
int a;
int b;
private:
int c;
protected:
char d;
double x;
};

sizeof(A)//24.为什么不是 3*4+1+8 = 21? 因为编译器要做优化,所以采用的是4Byte一体,也就符合我们常说的32位机的原理。也就是
机器的cpu可以同时处理32位二进制。所以地址线也做成了32位方便传输。编译器就将A优化为24Byte.但这只是对于32位机器有效。Vista等支持64位机
器。所以以后的VS2008等高级版本可能要将这个优化为可以被8B整除的字节数。

在字符表中,编译器大概会如此存储:类名  分隔符  变量名,这样即保证变量不会重名,又可以知道是那个类中的变量。

A::a      int         4

A::b      int         4

A::c       int         4

A::d      char      1

A::x      double   8

当调用sizeof(A)的时候,编译器会去寻找A类的所有变量,相加后如果不能被4整除,将变为最接近的4的倍数。

strlen()用于返回字符串的长度。但是不包括最后的’/0’

char * p = “google”; strlen(p);//结果为6

char * p = new char [20];
strlen(p)//???这里结果不能确定,原因是不知道何处有’/0’,strlen是查找到’/0’结束

strlen()函数的大概写法:

int strlen(const char * strSrc)
{
if(strSrc == NULL)
throw “NULL point…”;
int i = 0;
while(*strSrc++!=‘/0’)
i++;
return i;
}

不动者厚地,不息者高天。 无穷者日月,长在者山川。

松柏与龟鹤,其寿皆千年。

早出向朝市,暮已归下泉。形质及寿命,危脆若浮烟。

尧舜与周孔,古来称圣贤。借问今何在,一去亦不还。

我无不死药,万万随化迁。所未定知者,修短迟速间。

幸及身健日,当歌一尊前。何必待人劝,持此自为欢。

嗟嗟群物中,而人独不然。

要显示中文必须使用unsigned char型,如果使用char 就装不下了。

然后要明白一个unsigned char 其实只是装了一个中文字符的一半。打印的时候如果只打印一个unsigned
char有可能什么都看不到。所以逆转的时候要把两个unsigned char看成一个整体来交换。代码如下:

#include < iostream >
using namespace std;
int main( void )
{
unsigned char * string1 = new unsigned char [ 20 ];
unsigned char * b , * p;
b = p = string1;
while ( * p)
{

p ++ ;

}

p = p - 2 ;
while (p > b)
{
swap( * p, * b);
p ++ ;
b ++ ;
swap( * p, * b);
p = p - 3 ; // 转到下一个中文字符的第一个unsigned char
b ++ ;
}
cout << string1;
return 0 ;
}

其中的while(*p){p++;}p-=2;也可以用p = &string1[strlen(string1)-2]代替。。


char * Reverse( const char * str)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
kStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/
ContractedBlock.gif) … {

if (str == NULL)

throw " Null point " ;

int size = strlen(str);

if (size == 0 )

return “” ;


const char * p = str;

char * newStr = new char [size + 1 ];

char * temp = newStr;


while ( * p ++ );

p = p - 2 ; // 到达末尾的非’/0’字符

int i = 0 ;

while (p != str && i < size )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) … {

unsigned char * x = (unsigned char * )p;

if ( * x > 0x7f )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) … {

// DBCS

  • temp ++ = *-- p;
  • temp ++ = *++ p;

    p = p - 2 ;

    i += 2 ;
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockEnd.gif) }

    else
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
    rs/ContractedSubBlock.gif) … {

    // SBCS
  • temp ++ = * p -- ;

    i ++ ;
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockEnd.gif) }
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockEnd.gif) }

    if (i < size)
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
    rs/ContractedSubBlock.gif) … {
  • temp ++ = * str;
    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
    lockEnd.gif) }
  • temp = ’ /0 ’ ;

    return newStr;

    ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
    kEnd.gif) }

同时发现一个CSDN插入代码的bug。当插入代码中出现‘/0’的时候就会截断。所以我只能用’//0’代替了。

当字符串中有DBCS双字节字符时,使用同时转换两个。当有SBCS单字节字符串时转换一个。

(但是有些DBCS字符是占用两个以上空间的。但是没有考虑)这只是个简单的转换。

Character values of type unsigned char have a range from 0 to 0xFF
hexadecimal. A signed char has range 0x80 to 0x7F. These ranges translate to 0
to 255 decimal, and –128 to +127 decimal, respectively. The /J compiler option
changes the default from signed to unsigned.

char 是无符号的
unsigned char 是无符号的,里面全是正数

两者都作为字符用的话是没有区别的,但当整数用时有区别:
char 整数范围为-128到127,
而unsigned char 整数范围为0到255

多数情况下,char ,signed char 、unsigned char 类型的数据具有相同的特性然而当你把一个单字节的数赋给一个大整型数域时,便会看到
它们在符号扩展上的差异。另一个区别表现在当把一个介于128和255之间的数赋给signed char
变量时编译器必须先进行数值转化,同样还会出现警告。若使用十六进制进行赋值使用unsigned char
要方便一些.根据编译器具体实现情况不同,char要么和signed char等同,要么和unsigned char等同.

unsigned char*跟char *是一样的。

功能:统计字符串里面的汉字的个数 (gb2312编码内码大于0xa0)

char szText[]= “12345你好”;

l= strlen(szText);
int sum=0;
for (int i=0; i< l; i++)
if (szText[i] > 0xa0)
sum++;
sum/=2;

这样你根本统计出到任何汉字,
因为char是有符号的,打最大就是127,超过就变成复数了。比如7f 是127,那么80就是-1了。
这时候你一定要写成
unsigned char szText[]= “12345你好”;

这期的是动漫专刊,感觉要办刊物就要办的活些。让其他的成员也办几期。这次是动漫专刊,也花了点点不少精力。不过我认为是至今为止办的最好的一期了。

下载地址:

http://ss.hnu.cn/newweb/students/yuankan/download/
_ 青春缘代码动漫专刊.rar _

同样贴到迅雷上即可。

vc++中的多线程编程:


HANDLE hMutex; // Create a mutex with no initial owner. 必须要创建一个句柄

hMutex = CreateMutex( NULL, // no security attributes

FALSE, // initially not owned
"
MutexToProtectDatabase " ); // name of mutex
//
这个句柄只想信号量,第一个参数一半为NULL,第二个(初始化时是否被获得)false为现在可以被任何人使用
//
第三个参数是为信号量起名,方便以后查找该信号量
if
(hMutex == NULL)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
kStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/
ContractedBlock.gif) … {

// Check for error.一般不必这样用。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
kEnd.gif) }


BOOL FunctionToWriteToDatabase(HANDLE hMutex)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
kStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/
ContractedBlock.gif) … {

DWORD dwWaitResult; // Request ownership of mutex.

dwWaitResult = WaitForSingleObject(

hMutex, // handle to mutex

5000L ); // five-second time-out interval
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) switch (dwWaitResult) … {

// The thread got mutex ownership.

case WAIT_OBJECT_0:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) __try … {

// Write to the database.
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockEnd.gif) }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) __finally … {

// Release ownership of the mutex object.
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockStart.gif) ![](http://images.csdn.net/syntaxhighlighting/OutliningIndicato
rs/ContractedSubBlock.gif) if ( ! ReleaseMutex(hMutex)) … {

// Deal with error.
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockEnd.gif) }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockEnd.gif) break ; }

// Cannot get mutex ownership due to time-out.

case WAIT_TIMEOUT:

return FALSE;

// Got ownership of the abandoned mutex object.

case WAIT_ABANDONED:

return FALSE;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubB
lockEnd.gif) }

return TRUE;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBloc
kEnd.gif) }

DWORD dwWaitResult 只是为了判断信号量的归谁所有。 WaitForSingleObject() 相当与P()操作,参数有两个:第一个是
信号量,第二个是等待时间。INFINITE代表无限等待。5000L代表等待5秒,如果5秒内获得信号量,dwWaitResult==
WAIT_OBJECT_0,如果5秒没有得到信号量,则dwWaitResult== WAIT_TIMEOUT,而
WAIT_ABANDONED代表操作失败。 ReleaseMutex(hMutex)相当于V()操作。参数为信号量。

如果希望在一个函数中启动线程并调用该函数,应该这样写代码

void reading(void* name);这个函数一定要是void的返回类型。然后可以在调用函数中这样写:

_beginthread(&reading,0,(void*)english); 其中第一参数是要调用函数的函数指针。第二个函数是线程优先级一般为0。第三个
参数是个void指针,一般用来传函数的参数。如果想传多个参数只要把那个指针指向一个结构体就可以。到函数那里再转换为相应的结构体指针就可以了。

Sleep(5000L);这个函数一般是用来让线程睡眠的。参数是unsigned long,现在是睡5秒。
这只是多线程的编程常用到的几个函数。对于多线程编程还要注意同步和死锁,在这篇文字就不讨论了。

0%