#deinfe Const_BufLength 200

wchar_t strzh=new wchar_t[Const_BufLength]; //定义
 wprintf(L"Zhong text is: %ls\n", strzh); //使用


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

这几天研究Unicode,勤快些,把看到的东西觉得有用的都copy了下来,文章是拼凑出来的,所以看起来会觉得有些乱 :)。

 

 1. wprintf
Q : sizeof(wchar_t) = ?
A : 随编译器不同。(所以:在需要跨平台的时候尽量不用wchar_t) vc : sizeof(wchar_t) = 2;

Q: 在vc中,为什么直接使用wprintf(L"测试1234")会没有结果
A: 没有设置好locale,这样做

setlocale(LC_ALL ,"chs");
wprintf(L
"%s",L"测试1234");


或者(假设当前活动codepage为chs)

char scp[16];
int cp = GetACP();
sprintf(scp,
".%d",cp);
setlocale( LC_ALL, scp );
wprintf(L
"测试1234");


2. wcout
一样,不过设定locale,请用std::locale

    locale loc("chs");
    wcout.imbue(loc);
    wcout 
<< L"测试1234" << endl;

 

这篇文章应该是[netsin]的成果,我勤快,记下来。
注:wprintf是C的标准库函数,但wcout不是C++的标准成员,C++中的 L"……" 是宽字符,却未必是unicode字符,这与编译器实现相关。
[乾坤一笑]说:为什么 C/C++ 语言把 L"xx" 定义为由实现决定的呢?这显然是为了 C/C++ 的普适性、可移植性。Bjarne 的观点认为,C++ 的方式是允许程序员使用任何字符集作为串的字符类型。另外,unicode 编码已经发展了若干版本了,是否能永久适合下去也不得而知。有关 unicode 的详细论述以及和其它字符集的比较,我推荐你看《无废话xml》。


以下两段代码的执行环境是 windows xp professional 英文版,编译器是 VS2005RTM。

// C
#include <stdio.h>
#include <locale.h>
int main( void )
{
    setlocale( LC_ALL, "chs" );
    //setlocale( LC_ALL, "Chinese-simplified" );
    //setlocale( LC_ALL, "ZHI" );
    //setlocale( LC_ALL, ".936" );
    wprintf( L"中国" );

    return 0;
}

// C++
#include <iostream>
#include <locale>
using namespace std;
int main( void )
{
    locale loc( "chs" );
    //locale loc( "Chinese-simplified" );
    //locale loc( "ZHI" );
    //locale loc( ".936" );
    wcout.imbue( loc );
    std::wcout << L"中国" << endl;

    return 0;
}

说明:别混合使用 setlocale 和 std::locale 。

------------------------- 2006-07-05 记 -------------------------

 "VC知识库"                        编码为:56 43 D6 AA CA B6 BF E2 00                            // ANSI编码
L"VC知识库" 在VC++               中编码为:56 00 43 00 E5 77 C6 8B 93 5E 00 00                   // (windows口中的unicode)编码
L"VC知识库" 在GCC(Dev-CPP4990) 中编码为:56 00 43 00 D6 00 AA 00 CA 00 B6 00 BF 00 E2 00 00 00 // 只是将ANSI编码简单的加0
L"VC知识库" 在GCC(Dev-CPP4992) 中编译失败,报 Illegal byte sequence

L"VC知识库" 在 Dev-CPP4992 中解决步骤为:
a. 将文件保存为 utf-8 编码                                          // utf-8 是unicode的其中一种,但和(windows口中的unicode)不一样
b. 去掉BOM头:用二进制编辑器(比如VC)去掉刚才utf-8文件的前三个字节 // Linux/UNIX并不使用BOM
c. 使用 gcc/g++ 编译运行

经过以上解决步骤,在 dev-cpp4992 中
 "VC知识库" 编码为: 56 43 E7 9F A5 E8 AF 86 E5 BA 93 00 // utf-8编码,注意不再是ANSI编码了,因此用 printf/cout 将输出乱码
L"VC知识库" 编码为: 56 00 43 00 E5 77 C6 8B 93 5E 00 00 // (windows口中的unicode)编码

补充:在mingw32中使用wcout和wstring需要加一些宏,比如
#define _GLIBCXX_USE_WCHAR_T 1
#include <iostream>
int main( void )
{
    std::wcout << 1 << std::endl;
}
可以编译通过,但无法Link通过,在网上google了一下,stlport说mingw32有问题,mingw32说是M$的c runtime有问题。

 

 

1. printf 只能提供ANSI/MB 的输出,不支持输出unicode stream.
例如:
wchar_t test[]=L"测试1234";
printf(
"%s",test);
是不会正确输出的


2.wprintf 同样不会提供unicode output,
   但是他会把wchar_t的string转为locale的SB/MB字符编码,然后输出
例如:
wchar_t test[] = L"测试Test";
wprintf(L
"%s",test);
会输出??1234之类的字符串,或者不输出任何结果
因为wprintf没有办法把L"测试Test"转为默认的ANSI,需要设置locale
setlocale(LC_ALL,"chs");
wchar_t test[] 
= L"测试Test";
wprintf(L
"%s",test);
会有正确的输出
等同于printf("%ls",test);

综上:  CRT I/O functions do not provide Unicode output.

3. Window console自从NT4就是一个真正的unicode console
不过输出unicode string,只有使用Windows API, WriteConsoleW
例如:
wchar_t test[] = L"测试1234";
DWORD ws;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),test,wcslen(test),
&ws,NULL);
可以正确的输出而不需要设置locale,因为是真正的unicode的输出,跟codepage无关

4. 如何实现跨平台的console output
    不要使用wchar_t和wprintf,因为这些都依赖于编译器.
     ICU是IBM的一个成熟的跨平台支持unicode的libary,推荐使用

以下是ICU的uprintf实现

void uprintf(const UnicodeString &str) {
    
char *buf = 0;
    int32_t len 
= str.length();
    int32_t bufLen 
= len + 16;
    int32_t actualLen;
    buf 
= new char[bufLen + 1];
    actualLen 
= str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
    buf[actualLen] = 0;
    printf(
"%s", buf);
    delete buf;
}
它也是先把Unicode string转化为本地的codepage,然后printf,虽然也不是unicode output,但是跨平台,大多数情况会工作得很好。
后记:
mbstowcs(wchar_t *wcstr,  const char *mbstr, size_t count )等函数第三个参数
count:   The maximum number of multibyte characters to convert.
指待转换的多字节字符串相对于目前活动locale的字符个数加一。
比如:字符串"abc赵123"对于C locale而言count是strlen("abc赵123"),即8+1。
            而对于chinese-simplified.936而言count就是7+1。
count的计算必须和mbstowcs在同一个locale下。

阅读(5467) | 评论(1)| 复制链接

posted @ 2010-09-03 11:04 傅先生 阅读(1766) | 评论 (0)编辑 收藏

// UTF_8.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <locale.h>


// 把UTF-8转换成Unicode
static void UTF_8ToUnicode(wchar_tpOut,char *pText)
{
    
charuchar = (char *)pOut;
    
    
uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
    
uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
}


void UTF8_UNICODE(char *lpInint nLenwchar_t *lpOut)
{
    
int 0;
    
int 0;
    
whilenLen )
    {
        
wchar_t unicode 0;
        
iflpIn[i] > )
        {
            *((
char *)&unicode) = lpIn[i++];                       
        }
        
else                 
        
{
            
UTF_8ToUnicode(&unicodelpIn i);
            
+= 3;    
        }
        
lpOut[j++] = unicode;
    }
    
lpOut[j] = L'\0';
}

///////////------------ Unicode转UTF-8,字节 
int cUxU8(charpOut,wchar_tpText){ 
    
int ret 0
    
unsigned charpchar = (unsigned char *)pText
    
if(pText[0]<=0x7f){         // ASCII  0x00 ~ 0x7f 
        
pOut[0] = (char)pchar[0]; 
    }
else if(pText[0]<=0x7ff){  // 0x080 ~ 0x7ff 
        
pOut[0] = 0xc0|(pchar[1]<<2)|(pchar[0]>>6); 
        
pOut[1] = 0x80|(pchar[0]&0x3f); 
        
ret 1
    }
else{                      // 0x0800 ~ 0xFFFF 
        
pOut[0] = 0xe0|(pchar[1]>>4); 
        
pOut[1] = 0x80|((pchar[1]&0x0f)<<2)|(pchar[0]>>6); 
        
pOut[2] = 0x80|(pchar[0]&0x3f); 
        
ret 2
    } 
    
return ret



// ------------ Unicode转UTF-8,字符串 ---------------- 
int sUxU8(charpOut,wchar_tpText,int Len){ 
    
int i,j
    
for(i=0,j=0;i<Len;i++,j++){ 
        
j+=cUxU8(&pOut[j],&pText[i]); 
    } 
    
return j




int main(int argccharargv[])
{
    
    
wchar_t pL"111222ffdd你你你好你你你";  //测试代码
    
            // --输出Unicode其编码
    
int plen wcslen(p);
    
    
printf("开始unicode P :");
    
for(int i=0;i<plen;i++)//
    
{
        
printf("%X ",p[i]);
        
    }
    
printf("\n");    printf("\n");
    
    
    
//开始从unicode~~~UTF-8 转换  --并输出其编码
    
char pOut[500];

    
sUxU8(pOut,p,plen*2);
    
printf("开始UTF-8 pOut :");
    
for(i=0;i<plen*3;i++)
    {
        
printf("%X ",pOut[i]);
    }
    
printf("\n");    printf("\n");
    
    
    
//开始从UTF-8~~~unicode 还原        --并输出其编码
    
wchar_t wtest[500];
    
    
UTF8_UNICODE(pOutplen*2wtest);
    
printf("开始Unicode 还原:");
    
for(i=0;i<plen*3;i++)
    {
        
printf("%X ",wtest[i]);
    }
    
printf("\n");    printf("\n");
    
    
    
///输出 Unicode字符
    
setlocale(LC_ALL,"chs");
    
wchar_t test[] = L"测试Test";
    
wprintf(L"内容还原  : %s \n",wtest);
    

    
printf("Hello World!\n");
    
return 0;
}









posted @ 2010-09-03 10:55 傅先生 阅读(509) | 评论 (0)编辑 收藏

     摘要: /* 学生成绩管理程序 编制一个统计学生考试分数的管理程序。 设学生成绩已以一个学生一个记录的形式存储在文件中, 每位学生记录包含的信息有:姓名,学号和各门功课的成绩。 程序具有以下几项功能:求出各门课程的总分,平均分,按姓名, 按学号寻找其记录并显示,浏览全部学生成绩和按总分由高到低显示学生信息等。 */ #include <stdio.h> #def...  阅读全文

posted @ 2010-09-02 14:34 傅先生 阅读(177) | 评论 (0)编辑 收藏

     摘要: // getQQpassword.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include  <string> ...  阅读全文

posted @ 2010-08-29 11:50 傅先生 阅读(491) | 评论 (0)编辑 收藏



16进




/////////////////
char byte

区别:char 有FFFFFB6
            byte 正数

//////////显示“烫”等杂字符--解决办法

数值类型必须为char*
1,bufCopyData[itest]='\0';//整体初始化
2,char *dw_imtype=new char[2+2];//申请初始化

posted @ 2010-08-28 07:20 傅先生 阅读(164) | 评论 (0)编辑 收藏


枚举类
1,注册表
2,文件
3,
4,
5,

搜索类
1,内存
2,文件
3,注册表
4,
5

posted @ 2010-08-28 05:59 傅先生 阅读(134) | 评论 (0)编辑 收藏

///////////////1,枚举主体窗口
///////////////2,枚举窗体类下的子窗口



#include 
<Stdio.h>
#include <Windows.h>

BOOL CALLBACK EnumWindowsProc(HWND hWndLPARAM lParam);
BOOL CALLBACK EnumChildProc(HWND hwndLPARAM lParam );

int mainint argccharargv[] )
{
    
HWND m_htest FindWindow("TXGuiFoundation",NULL);//(1,lpclassname 2,lpwindowsname)
    //   EnumWindows( EnumWindowsProc, NULL );
    
if(m_htest==NULL)
    {
        
printf("No find something!!\n");
    }
    
    
EnumChildWindows(m_htest,EnumChildProc,NULL);
    
return 0;
}

HWND m_hwndFind[1000] = {0};
int  m_num 0;


BOOL CALLBACK EnumChildProc(HWND hWndLPARAM lParam )
{
    
//         if(::GetWindowLong(hWnd,GWL_STYLE) & WS_VISIBLE)
    //   {
    
    
char sBuf[256];
    ::
GetClassName(hWnd,NULL,254);
//    ::GetWindowText(aHwnd,WndCaption,254);
    
::GetWindowTexthWndsBuf256 );
    
printf"%s\n"sBuf );
    
m_hwndFind[m_num] = hWnd;
    
m_num++;
    
//  }
    
return 1;
    
}



BOOL CALLBACK EnumWindowsProc(HWND hWndLPARAM lParam)
{
    
if(::GetWindowLong(hWnd,GWL_STYLE) & WS_VISIBLE)
    {
        
char sBuf[256];
        
//获取窗口标题
        
::GetWindowTexthWndsBuf256 );
        
if strcmpsBuf"我的电脑" ) == )
        {
            
//在发现我的电脑时设置其标题为www.a3gs.com
            
::SetWindowTexthWnd"www.a3gs.com" );
        }
        
printf"%s\n"sBuf );
        
m_hwndFind[m_num] = hWnd;
        
m_num++;
    }
    
return 1;
}

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



#include <windows.h>
BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    
char className[]="TXGuiFoundation";

    
HWND hWnd=::FindWindow(className,NULL);
    
if(hWnd)
    {
        ::
EnumChildWindows(hWnd,EnumChildProc,0);
        
return 0;
    }
    
MessageBox(NULL,"fail!","fail",MB_OK);
    
return 0;
}


BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam)
{
    
char temp1[256],temp2[256];
    ::
GetWindowText(hWnd,temp1,255);


    
wsprintf(temp2,"hwnd:%x text: %s",hWnd,temp1);
    
MessageBox(NULL,temp2,"cwnd",MB_OK);
    
return true;
}


posted @ 2010-08-28 05:56 傅先生 阅读(1953) | 评论 (0)编辑 收藏

Window知料整理2010-08-09 19:17
1
,

2,

3,

BOOL CALLBACK EnumWindowsProc(HWND hWndLPARAM lParam)

int main(){

EnumWindowsEnumWindowsProcNULL );

}

BOOL CALLBACK EnumWindowsProc(HWND hWndLPARAM lParam)
{
if(::GetWindowLong(hWnd,GWL_STYLE) & WS_VISIBLE)
{
   
char sBuf[256];
   
//获取窗口标题
   
::GetWindowTexthWndsBuf256 );
   
if strcmpsBuf"我的电脑" ) == )
   {
    
//在发现我的电脑时设置其标题为www.a3gs.com
    
::SetWindowTexthWnd"www.a3gs.com" );
   }
   
char sclassname[256];
   
GetClassName(
    
hWnd,sclassname,256
    
);
   
if(strcmp(sclassname,"TXGuiFoundation")==0)
   {
   
printf"------------------------ \n");
   
printf"%s -- %d\n --%s---%s \n"sBuf ,hWnd ,lParam,sclassname );
   
printf"           \n" );
   }
   
m_hwndFind[m_num] = hWnd;
   
m_num++;
}
return 1;
}

HWND hWnd GetForegroundWindow();//GetActiveWindow(); //'得到活动窗口的句柄

GetWindowText(hWnd,s_Buf,255);

printf("tttt   %s \n",s_Buf);
 

posted @ 2010-08-28 05:28 傅先生 阅读(178) | 评论 (0)编辑 收藏

define的用法
2007-12-22 08:04
1.简单的define定义

#define MAXTIME 1000

一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写

if(i<MAXTIME){.........}

编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。

这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。

2.define的“函数定义”

define可以像函数那样接受一些参数,如下

#define max(x,y) (x)>(y)?(x):(y);

这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。

但是这样做的话存在隐患,例子如下:
#define Add(a,b) a+b;
在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了
c*a + b*d

另外举一个例子:
#define pin (int*);
pin a,b;
本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。
这是应该使用typedef来代替define,这样a和b就都是int型指针了。

所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

3.宏的单行定义
#define A(x) T_##x
#define B(x) #@x

#define C(x) #x
我们假设:x=1,则有:
A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"

(这里参考了 hustli的文章)

3.define的多行定义

define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心)

#define MACRO(arg1, arg2) do { \
/* declarations */ \
stmt1; \
stmt2; \
/* ... */ \
} while(0) /* (no trailing ; ) */
关键是要在每一个换行的时候加上一个"\"


4.在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

就是:
#ifdef WINDOWS
......
......
#endif
#ifdef LINUX
......
......
#endif

可以在编译的时候通过#define设置编译环境

5.如何定义宏、取消宏

//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
普通宏
#define PI (3.1415926)

带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))
关键是十分容易产生错误,包括机器和人理解上的差异等等。

6.条件编译
#ifdef XXX…(#else) …#endif
例如 #ifdef DV22_AUX_INPUT
#define AUX_MODE 3
#else
#define AUY_MODE 3
#endif
#ifndef XXX … (#else) … #endif

7.头文件(.h)可以被头文件或C文件包含;
重复包含(重复定义)
由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。
通过条件编译开关来避免重复包含(重复定义)
例如
#ifndef __headerfileXXX__
#define __headerfileXXX__

文件内容

#endif

posted @ 2010-08-25 00:50 傅先生 阅读(291) | 评论 (0)编辑 收藏

switch-case语句用法
2007-12-25 08:11

if语句处理两个分支,处理多个分支时需使用if-else-if结构,但如果分支较多,则嵌套的if语句层就越多,程序不但庞大而且理解也比较困难.因此,C语言又提供了一个专门用于处理多分支结构的条件选择语句,称为switch语句,又称开关语句.使用switch语句直接处理多个分支(当然包括两个分支).其一般形式为:

引用
switch(表达式)
{
      case 常量表达式1:
         语句1;
      break;
     
      case 常量表达式2:
         语句2;
      break;

……
      case 常量表达式n:
         语句n;
      break;

      default:
         语句n+1;
      break;
}



switch语句的执行流程是:首先计算switch后面圆括号中表达式的值,然后用此值依次与各个case的常量表达式比较,若圆括号中表达式的值与某个case后面的常量表达式的值相等,就执行此case后面的语句,执行后遇break语句就退出switch语句;若圆括号中表达式的值与所有case后面的常量表达式都不等,则执行default后面的语句n+1,然后退出switch语句,程序流程转向开关语句的下一个语句.如下程序,可以根据输入的考试成绩的等级,输出百分制分数段:

引用
switch(grade)
{
    case 'A': /*注意,这里是冒号:并不是分号;*/
       printf("85-100\n");
    break; /*每一个case语句后都要跟一个break用来退出switch语句*/
    case 'B': /*每一个case后的常量表达式必须是不同的值以保证分支的唯一性*/
       printf("70-84\n");
    break;
    case 'C':
       printf("60-69\n");
    break;
    case 'D':
       printf("<60\n");
    break;
    default:
       printf("error!\n");
}

(2) 如果在case后面包含多条执行语句时,也不需要像if语句那样加大括号,进入某个case后,会自动顺序执行本case后面的所有执行语句.如:

引用
{
    case 'A':
     if(grade<=100)
       printf("85-100\n");
     else
       printf("error\n");
    break;
……

(3) default总是放在最后,这时default后不需要break语句.并且,default部分也不是必须的,如果没有这一部分,当switch后面圆括号中表达式的值与所有case后面的常量表达式的值都不相等时,则不执行任何一个分支直接退出switch语句.此时,switch语句相当于一个空语句.例如,将上面例子中switch语句中的default部分去掉,则当输入的字符不是"A","B","C"或"D"时,此switch语句中的任何一条语句也不被执行.

(4) 在switch-case语句中,多个case可以共用一条执行语句,如:

引用
……
case 'A':
case 'B':
case 'c':
printf(">60\n");
break;
……

在A,B,C3种情况下,均执行相同的语句,即输出">60".

(5) 最开始那个例子中,如果把每个case后的break删除掉,则当greak='A'时,程序从printf("85-100\n")开始执行,输出结果为:

引用
85-100
70-84
60-69
<60
error

这是因为case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即"只是开始执行处的入口标号".因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行,而且执行完一个case后面的语句后,若没遇到break语句,就自动进入下一个case继续执行,而不在判断是否与之匹配,直到遇到break语句才停止执行,退出break语句.因此,若想执行一个case分之后立即跳出switch语句,就必须在此分支的最后添加一个break语句.

引用
main() /*完成两个数简单的四则运算*/
{
   float a,b;
   char c1;
   printf("Please enter a,b and op:");
   scanf("%f%c%f",&a,&c1,&b);
   switch(c1)
   {
      case '+':
        printf("%f+%f=%f\n",a,b,a+b);
      break;
      case '-':
        printf("%f-%f=%f\n",a,b,a-b);
      break;
      case '*':
        printf("%f*%f=%f\n",a,b,a*b);
      break;
      case '/':
        if(b!=0.0) /*分母不能等于0*/
          printf("%f/%f=%f\n",a,b,a/b);
        else
        printf("error!\n");
      break;
      default:
        printf("error!\n");
      break;
   }
}

posted @ 2010-08-25 00:47 傅先生 阅读(16143) | 评论 (0)编辑 收藏

仅列出标题
共6页: 1 2 3 4 5 6 

posts - 54, comments - 5, trackbacks - 0, articles - 2

Copyright © 傅先生