全部博文(158)
分类: WINDOWS
2010-01-03 16:06:23
c的string库与windows的string库比较
1. strlen, wcslen, lstren
先看各个函数的声明:
Strlen: size_t
strlen(const char* string);
Wcslen: size_t
strlen(const wchar_t* string);
Lstrlen: int
lstrlen(lpString);
Strlen用于ANSI字符集, wcslen用于UNICODE,lstrlen用于ANSI或者UNICODE情况, 取决于UNICODE是否定义, 请看代码:
#include
#include
int main() {
char* p = "你好
世界";
int len = strlen(p);
printf("the length of string is
%d\n", len);
}
Result: the length
of string is 9
#include
int main() {
char* p = "你好
世界";
int len = wcslen(p);
printf("the length of string is
%d\n", len);
}
Result: the length
of string is 5
#include
int main() {
char* p = "你好
世界";
int len = lstrlen(p);
printf("the length of string is
%d\n", len);
}
Result: the length
of string is 9
// warning: you
must define this two macro befone any header file.
#define UNICODE
#define _UNICODE
#include
int main() {
char* p = "你好
世界";
int len = lstrlen(p);
printf("the length of string is
%d\n", len);
}
Reslut: the length
of string is 5.
大家看清楚了吧, 所以说我们一般用lstrlen代替strlen与wcslen进行字符串的长度计算, 定义了_UNICODE与UNICODE就与wcslen相同。
我们最常见的strlen写法是:
#include
size_t
strlen(const char* string) {
size_t length = 0;
for(; *string++ != '\0';)
length++;
return length;
}
int main() {
char* p = "你好
世界";
int len = strlen(p);
printf("the length of string is
%d\n", len);
}
2. strcpy, wcscpy, lstrcpy
先看一下这几个函数的声明:
Strcpy: char*
strcpy(char* destination, const char* src);
Wcscpy: wchar_t*
wcscpy(wchar_t* destination, const char* src);
Lstrcpy: LPTSTR
lstrcpy(LPTSTR destination, LPCTSTR src);
Strcpy用于ANSI字符集, wcscpy用于UNICODE, lstrcpy视情况而定。
#include
int main() {
char str1[] = "你好
世界";
char str2[10];
char str3[10];
strcpy(str2, str1);
strcpy(str3, "世界
你好");
printf("the str1 is %s\n",
str1);
printf("the str2 is %s\n", str2);
printf("the str3 is %s\n",
str3);
}
#include
#include
#include
int main() {
wchar_t str1[] = L"你好
世界";
wchar_t str2[10];
wchar_t str3[10];
wcscpy(str2, str1);
wcscpy(str3, L"世界
你好");
// we have to do
this step to make wprintf output the right string,
// in fact,
wprintf does’t support UNICODE.
setlocale(LC_ALL,"chs");
wprintf(L"the str1 is %ls\n",
str1);
wprintf(L"the str2 is %ls\n",
str2);
wprintf(L"the str3 is %ls\n",
str3);
}
3. strcat, wcscat, lstrcat
看一下函数原型:
Strcat: char*
strcat(char* destination, const char* src);
Wcscat: wchar_t*
strcat(wchar_t* destination, const wchar_t* src);
Lstrcat: LPTSTR*
lstrcat(LPTSTR destination, LPTCSTR src);
#include
#include
int main() {
char str[20] = "你好
世界";
char str1[] = " 世界
你好";
strcat(str, str1);
printf("str is %s\n",str);
}
4. strcmp, 我没有看到windows版的,
这是可以理解的。
Strcmp: int
strcmp(const char* str1, const char* str2);
#include
#include
int main() {
char str1[] = "hello 世界";
char str2[] = "hello world
too";
int cmp = strcmp(str1, str2);
if(cmp > 0)
puts("str1 is
bigger.\n");
else if(cmp == 0)
puts("str equals str2");
else
puts("str1 is litter");
}
5. strncpy, strncat, strncpy, 请记住, 它们的结果不会以NUL字节结尾!
Char*
strncpy(char* destination, const char* src, size_t len);
Char*
strncat(char* destination, const char* src, size_t len);
Int strncmp(const
char* str1, const char* str2, size_t len);
6. 字符串查找基础, 这个部分是非常有意思的。请看:
A. 查找一个字符:
Char* strchr(const
char* str, int ch);
Char*
strrchr(const char* str, int ch);
#include
#include
int main() {
char str[] = "你好
世世世世界";
char* p = strchr(str, '世');
int pos;
p--;
pos = p - str + 1;
printf("pos is %d\n", pos);
printf("str is %s\n", p);
}
把strchr换成strrchr看看……
当然这个版本还有UNICODE的。
Wchar*
wcschr(const wchar_t* str, wchar_t c);
#include
int main() {
wchar_t str[] = L"你好
世世世界";
wchar_t* p = wcschr(str, L'世');
printf("the pos is %d\n", p -
str + 1);
}
不知道大家看出来了什么区别没有, 我们发现当用ANSI版本的strchr时,
我们的返回结果必须向前一个字节, 而在UNICODE却不用这么做?
非常简单, 一个汉字在ANSI字符集是二个字节, 我们用ANSI的strchr查找时, 指针将指向第二个汉字的第二个字节而不是第一个字节, 所以如果你要想输出的时候,必须将指针向前移一个指针, 要不然会乱码, UNICODE当然不会出现这种结果了。
同理我们还存在strrchr的UNICODE版本:
Wchar_t*
wcsrchr(const wchar_t* str, wchar_t int c);
记住:没有lstrchr, lstrrchr这样的函数!!!!!
B. 查找几个字符:
Char*
strpbrk(const char* str, const char* group);
Wchar*
wcspbrk(const wchar_t* str, const wchar_t* group);
没有lstrpbrk这样的函数!!!!!!!!
#include
#include
int main() {
char str1[] = "hello world";
char str2[] = "eod";
char* p = strpbrk(str1, str2);
while(p != NULL) {
printf("%c\n", *p);
p = strpbrk(p + 1, str2);
}
}
如果用strpbrk来查找中文, 那简直是种折磨, 所以我一般不用来strpbrk来查找中文, 用UNICODE来做:
#include
#include
int main() {
wchar_t str1[] = L"你好
好好
世世
办办
世界世界";
wchar_t str2[] = L"世界";
wchar_t* p = wcspbrk(str1, str2);
setlocale(LC_ALL, "chs");
while(p != NULL) {
wprintf(L"%c\n", *p);
p = wcspbrk(p + 1, str2);
}
}
哪位哥们用ANSI版的strpbrk做一下?
C.查找一个字符串, 这个比较有意思……
Char* strstr(const
char* str1, const char* str2);
Wchar_t*
wcsstr(const wchar_t* str1, const wchar_t* str2);
没有lstrstr!!!!!!!!!!!!!!!!!!!!!!!!
#include
#include
int main() {
char str1[] = "this is a simple
string";
char* pch;
pch = strstr(str1, "simple");
printf("%s\n", pch);
}
咱们换个中文试试……
#include
#include
int main() {
char str1[] = "这是一个简单的字符串";
char* pch;
pch = strstr(str1, "简单");
printf("%s\n", pch);
}
结果是:简单的字符串
为什么这次又对了呢, 因为查找的是字符串,不是单个字符!!!!!!!!!!
UNICODE版:
#include
#include
#include
#include
int main() {
wchar_t str[] = L"这是一个简单的字符串";
wchar_t* pch;
pch = wcsstr(str, L"简单");
setlocale(LC_ALL, "chs");
wprintf(L"%s\n", pch);
}
C. strspn, strcspn, wcsspn, wcscspn这几个函数有点难用哈……
size_t
strspn(const char* str1, const char* str2);
返回str1中第一个不与str2不匹配的字符,从0开始
size_t
strcspn(const char* str1, const char* str2);
返回str1中第一个与str2匹配的字符,从0开始
size_t
wcsspn(const wchar_t* str1, const wchar_t* str2);
返回str1中第一个不与str2不匹配的字符,从0开始
size_t
wcscspn(const wchar_t* str1, const wchar_t* str2);
返回str1中第一个与str2匹配的字符,从0开始
且看代码:
#include
#include
int main() {
char str1[] = "1569hehe";
char str2[] = "1234567890";
int pos = strspn(str1, str2);
printf("pos is %d\n", pos);
}
Result: pos is 4
#include
#include
int main() {
char str1[] = "hehe3459";
char str2[] = "1234567890";
int pos = strcspn(str1, str2);
printf("pos is %d\n", pos);
}
Result: pos is 4
哈哈,我们已经开始了解正规表达式来了, 这个函数我就觉得功能强大……
上面的函数用中文试试?
#include
#include
int main() {
char str1[] = "我哪里知道ksks";
char str2[] = "我也不知道啊";
int pos = strspn(str1, str2);
printf("pos is %d\n", pos);
}
Reslut: pos is 2.
为什么是2, 因为从0开始,中文二个字节。
我们记忆的时候只要记住一个函数strcpn, 它表示在str1中第一个不与str2匹配的位置, strcspn相反, 其他两个函数一样啦……
看UNICODE版:
#include
int main() {
wchar_t str1[] = L"我哪里知道ksks";
wchar_t str2[] = L"我也不知道啊";
int pos = wcsspn(str1, str2);
printf("the pos is %d\n", pos);
}
Reslut: the pos is
1
为什么这个结果与上面的不同, 你这么问说明你的基础还不扎实……
D.
查找标记, strtok函数, 这个函数也算是正规表达里面的一部分,比较有意思……
Char* strtok(char*
str, const char* delimiters);
Wchar_t*
wcstok(wchar* str, const wchar_t* delimiters);
可以这么看这个函数, str包含某个字符, 如果这个字符在delimiters指向的串里面,就把它变成NUL字节,
通过连续地呼叫, 把所有具有这种特性的字符都变成NUL字节, 这样说可能太复杂, 且看代码:
#include
#include
int main() {
char str[] = "a#b#c#d";
char* p = strtok(str, "#");
while(p != NULL) {
printf("%c\n", *p);
p = strtok(NULL, "#");
}
}
Result:
a
b
c
c
理解了吧, 也就是取#与#之间的字符串了……
第一次呼叫后, 要吧strtok的第一个参数设为NULL!!!!
标准库这么解释这个函数的功能:
char * strtok ( char * str, const char * delimiters );
Split string into tokens
A sequence of calls to this function split str
into tokens, which are sequences of contiguous characters separated by any of
the characters that are part of delimiters.
On a first call, the function expects a C string as argument for str,
whose first character is used as the starting location to scan for tokens. In
subsequent calls, the function expects a null pointer and uses the position
right after the end of last token as the new starting location for scanning.
To determine the beginning and the end of a token, the function first scans
from the starting location for the first character not
contained in delimiters (which becomes the beginning of the token).
And then scans starting from this beginning of the token for the first
character contained in delimiters, which becomes the end of the token.
This end of the token is automatically replaced by a null-character by
the function, and the beginning of the token is returned by the
function.
Once the terminating null character of str has been found in a call to strtok,
all subsequent calls to this function with a null pointer as the first argument
return a null pointer.
上面的代码变换一下:
#include
#include
int main() {
char str[] = "a#b#c-d";
char* p = strtok(str, "#-");
while(p != NULL) {
printf("%c\n", *p);
p = strtok(NULL, "#-");
}
}
结果与上面一样,理解了吧,呵呵
我们用中文作为delimiters试试:
我们来看一下这个函数的UNICODE版:
#include
#include
int main() {
char str[] = "a我b#c-d";
char* p = strtok(str, "我-#");
while(p != NULL) {
printf("%c\n", *p);
p = strtok(NULL, "我#-");
}
}
结果是一样的,好使, 目前我们只发现strchr不怎么太好使,其它没有问题!!!!!
看看UNICODE版本的:
#include
#include
int main() {
wchar_t str[] = L"a我b#c-d";
wchar_t* p = wcstok(str, L"我-#");
setlocale(LC_ALL, "chs");
while(p != NULL) {
wprintf(L"%c\n", *p);
p = wcstok(NULL, L"我#-");
}
}
结果与上面是一样的。
E.
字符操作函数
(1) Int iscntrl(int c)
Int isprintf(Int c)
这两个函数是相反的, 控制字符都是不可打印的, 可打印的不是控制字符
#include
#include
#include
int main() {
int c;
int i = 0;
for(c = 0; c < 125; c++) {
if(iscntrl(c))
continue;
printf("%c\t", c);
i++;
if(i % 5 == 0)
putchar('\n');
}
}
Result:
!
" # $
% & '
( )
* +
, - .
/ 0
1 2 3
4 5
6 7 8
9 :
; < =
> ?
@ A B
C D
E F G
H I
J K L
M N
O P Q
R S
T U V
W X
Y Z [
\ ]
^ _ `
a b
c d e
f g
h i j
k l
m n o
p q
r s t
u v
w x y
z {
|
我们试一下试是否对UNICODE有用: 这个问题太复杂了,不考虑。
Int isalnum(int c)
: 数字或者字母
Int isalpha : 字母
Int isdigit : 十进制数字
Int isxdigit: 十六进制
Isspace: 是否为空格, 换行,回国, tab
Ispunct: 标点符号
Isgraph: 图形符号
Islower: 小写
Isupper: 大写
大小写转换:
Int tolower(int
c);
Int toupper(int
c);
返回值为转换后的形式
#include
#include
#include
int main() {
char str[] = "It is A TEst";
int i = 0;
while(str[i]) {
putchar(tolower(str[i]));
i++;
}
putchar('\n');
}
F.内存操作
我只说两个最常用的函数:
Void* memcpy(void*
destination, const void* src, size_t length)
看起来很简单,length代表字节, 这个要注意
Void* memset(void*
memory, int ch, size_t length);
他们都包含在string.h中