引: String.h头文件中主要包含了1个变量类型、1个宏定义和22个用于处理C语言中字符数组(字符串)的函数。下面进行一一介绍。
注释信息部分对String.h头文件的作用进行了说明,提示内容:该文件包含了一些用于字符串操作的函数声明。
顾名思义,编译预处理是在对C程序进行编译之前所做的处理,主要包括:宏定义、头文件包含、条件编译。这里仅对一些条件编译的内容作以说明。
可以看到,注释结束后第一行代码如下所示,
#if _MSC_VER > 1000 //如果MicroSoft的C编译器版本号大于1000对应的那个版本号(如:VC++6.0版本即为1200) #pragma once //头文件只编译一次,是为了类库的兼容性考虑,像以前的C的类库 #endif //结束条件编译这里的“MSC”是由两部分组成的:①MS——MicroSoft的缩写;②C:表示C编译器,MSC表示的是C编译器。而后边的“VER”想必大家都不陌生,是单词“VERSION”的缩写,代表版本。部分微软编译器版本号和“MSC_VER”参数之间的对应关系如下所示,
接下来会看到如下所示的、用于区分不同操作系统的预编译处理语句,
#if !defined(_WIN32) && !defined(_MAC) //如果没有bai定义_WIN32和_MAC宏 #error ERROR: Only Mac or Win32 targets supported! //是编译器产生一个错误,提示信息为:Only Mac or Win32 targets supported![仅支持Mac和Win32系统] #endif“#error”用于使编译器产生一个错误,即:通常所看到的编译窗口下面的错误信息。另外警告信息可通过“#warning”命令来产生,对应于编译窗口下面的警告信息。 关于“#if !defined”语句,作用是:判断某个宏是否已经被定义,可看如下所示的例子,
#if defined a //要检查a是否定义,如果已经定义 #undef a //用#undef语句解除定义 #define a 200 //并重新定义a为200 #endif //结束预处理先来看如下一段条件编译处理的结构,
#ifdef __cplusplus //检测当前文件是否为.cpp文件 extern "C" { //如果是.cpp文件,就将代码段按照C语言的方式进行编译(C和C++之间的兼容性处理) #endif //一段代码 #ifdef __cplusplus } #endif①“_cplusplus”宏:是.cpp文件默认定义的宏。用来判断是否为.cpp文件。 ②extern “C”:告诉编译器,这部分代码按C语言的方式进行编译,而不是C++的。 该处理主要是为了尽量避免C和C++之间存在的差异对程序运行的影响,譬如两者对NULL的定义存在不同,
#ifndef NULL //如果当前头文件中没有定义NULL #ifdef __cplusplus //如果当前文件是.cpp(C++)源文件 #define NULL 0 //将NULL的值定义为0 #else //否则(如果是.C源文件) #define NULL ((void *)0) //将NULL的值定义为万能指针类型的0 #endif //#ifdef __cplusplus结束 #endif //#ifndef NULL结束接触过Windows程序设计的盆友们肯定认识“wchar_t”这种宽字符类型,在String.h文件中可以看到该种类型的定义方式如下,
#ifndef _MAC //如果未定义_MAC_宏 #ifndef _WCHAR_T_DEFINED //如果没有定义_WCHAR_T_DEFINED typedef unsigned short wchar_t;//则定义unsigned short为新的类型wchar_t #define _WCHAR_T_DEFINED #endif //结束#ifndef _WCHAR_T_DEFINED #endif /*结束 ndef _MAC */wchar_t全称是wide character type,即:宽字符。最常见的宽字符编码方式就是unicode了,utf-16和utf-32都是unicode编码。wchar_t也主要以这两种方式实现,提供了一种国际通用的字符实现。
接下来看一下“size_t”类型的定义,同样是一块条件编译代码段,如下所示,
#ifndef _SIZE_T_DEFINED typedef unsigned int size_t; //typedef关键字 #define _SIZE_T_DEFINED #endif可以看到类型“size_t”是由typedef关键字通过“unsigned int ”(无符号整型)来定义的,并且该类型和sizeof(type)函数的返回值类型相同。
关于其具体介绍已经在2部分的③中进行说明,通常NULL用于将一指针变量的值赋为空,即修改为“空指针”(有别于“野指针”,具体可查看文章:初步理解指针——C语言,空指针与野指针部分)。
好了,上面说了一大堆废话,我们所关注的核心还是String.h头文件为我们提供的可用函数有哪些,下面通过不同的分类就:函数参数、返回值等信息对其进行一一介绍。
String.h头文件中提供了5个可用于字符串复制的函数,比较特别的是:memset(),可用于字符串内容的清空。
【1】void* memcpy(void *, const void *, size_t); 【2】char* strcpy(char *, const char *); 【3】char* strncpy(char *, const char *, size_t n); 【4】void* memset(void *, int, size_t); 【5】void* memmove(void *, const void *, size_t);其作用如下,
函数作用memcpy()对类型没有要求,复制指定的前n个字符到目标数组中,strcpy()复制字符串,遇到'\0'即结束复制strncpy()复制字符串,遇到'\0'即结束复制,如果未遇到原串的'\0’,在复制够n个时同样会结束复制,同时一定会被参数中指定的n个字符填充(不够的补'\0')memset()复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。通常用于字符串清空处理memmove()用于从 src 复制 n 个字符到 dest 的函数 下面看一个例子, //复制字符串 void copyString(){ char src[10]="asdgdfdsa\0"; char dest[20]; //0-memcpy memcpy(dest,src,10); printf("%s\tlen=%d\n",dest,strlen(dest)); //1-strcpy strcpy(src,dest); printf("%s\tlen=%d\n",dest,strlen(dest)); //3-strncpy strncpy(dest,src,10); printf("%s\tlen=%d\n",dest,strlen(dest)); //4-字符串清空操作 memset(src,0,10); printf("%s\tlen=%d\n",src,strlen(src)); }运行结果:
示例如下,
//分割字符串 void splitString(){ char src[20]="a,s,c,d,fdf,we,"; char* res=strtok(src,","); printf("%s\n",res); while(res=strtok(NULL,",")){ printf("%s\n",res); } }执行结果,
执行结果,
【1】int memcmp(const void *str1, const void *str2, size_t n);把 str1 和 str2 的前 n 个字节进行比较。 【2】int strcmp(const char *str1, const char *str2);把 str1 所指向的字符串和 str2 所指向的字符串进行比较。 返回0 表示相等,非0表示不相等 【3】int strncmp(const char *str1, const char *str2, size_t n);把 str1 和 str2 进行比较,最多比较前 n 个字节。 【4】int strcoll(const char *str1, const char *str2);把 str1 和 str2 进行比较,结果取决于 LC_COLLATE 的位置设置代码示例如下,
//比较字符串 void comString(){ char src[]="hate"; char dest[20]="love"; printf("%d\n",strcmp(src,dest)); printf("%d\n",strncmp(src,dest,3)); } //输出结果: -1 -1示例代码如下:
//字符串查找函数 void searchString(){ char src[10]="asdgdfdsa\0"; //strstr-返回目标字串的指针位置 printf("%s\n",strstr(src,"dgd")); //strchr-返回目标字符的指针位置 printf("%s\n",strchr(src,'s')); }从中可以看到,字符串查找函数主要针对字符和子字符串两类对象进行查找,应有所区分。
如下所示,
【1】size_t strxfrm(char *dest, const char *src, size_t n);根据程序当前的区域选项中的 LC_COLLATE 来转换字符串 src 的前 n 个字符,并把它们放置在字符串 dest 中 【2】char *strerror(int errnum);从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。 【3】size_t strlen(const char *str);计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。该头文件的内容可通过VC++6.0/VS系列的集成开发环境来查看,下面是该头文件的主要内容。
/*** *string.h - declarations for string manipulation functions * * Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. * *Purpose: * This file contains the function declarations for the string * manipulation functions. * [ANSI/System V] * * [Public] * ****/ #if _MSC_VER > 1000 #pragma once #endif #ifndef _INC_STRING #define _INC_STRING #if !defined(_WIN32) && !defined(_MAC) #error ERROR: Only Mac or Win32 targets supported! #endif #ifdef __cplusplus extern "C" { #endif /* Define _CRTIMP */ #ifndef _CRTIMP #ifdef _DLL #define _CRTIMP __declspec(dllimport) #else /* ndef _DLL */ #define _CRTIMP #endif /* _DLL */ #endif /* _CRTIMP */ /* Define __cdecl for non-Microsoft compilers */ #if ( !defined(_MSC_VER) && !defined(__cdecl) ) #define __cdecl #endif /* Define _CRTAPI1 (for compatibility with the NT SDK) */ #ifndef _CRTAPI1 #if _MSC_VER >= 800 && _M_IX86 >= 300 #define _CRTAPI1 __cdecl #else #define _CRTAPI1 #endif #endif #ifndef _SIZE_T_DEFINED typedef unsigned int size_t; #define _SIZE_T_DEFINED #endif #ifndef _MAC #ifndef _WCHAR_T_DEFINED typedef unsigned short wchar_t; #define _WCHAR_T_DEFINED #endif #endif /* ndef _MAC */ #ifndef _NLSCMP_DEFINED #define _NLSCMPERROR 2147483647 /* currently == INT_MAX */ #define _NLSCMP_DEFINED #endif /* Define NULL pointer value */ #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif /* Function prototypes */ #ifdef _M_MRX000 _CRTIMP void * __cdecl memcpy(void *, const void *, size_t); _CRTIMP int __cdecl memcmp(const void *, const void *, size_t); _CRTIMP void * __cdecl memset(void *, int, size_t); _CRTIMP char * __cdecl _strset(char *, int); _CRTIMP char * __cdecl strcpy(char *, const char *); _CRTIMP char * __cdecl strcat(char *, const char *); _CRTIMP int __cdecl strcmp(const char *, const char *); _CRTIMP size_t __cdecl strlen(const char *); #else void * __cdecl memcpy(void *, const void *, size_t); int __cdecl memcmp(const void *, const void *, size_t); void * __cdecl memset(void *, int, size_t); char * __cdecl _strset(char *, int); char * __cdecl strcpy(char *, const char *); char * __cdecl strcat(char *, const char *); int __cdecl strcmp(const char *, const char *); size_t __cdecl strlen(const char *); #endif _CRTIMP void * __cdecl _memccpy(void *, const void *, int, unsigned int); _CRTIMP void * __cdecl memchr(const void *, int, size_t); _CRTIMP int __cdecl _memicmp(const void *, const void *, unsigned int); #ifdef _M_ALPHA /* memmove is available as an intrinsic in the Alpha compiler */ void * __cdecl memmove(void *, const void *, size_t); #else _CRTIMP void * __cdecl memmove(void *, const void *, size_t); #endif _CRTIMP char * __cdecl strchr(const char *, int); _CRTIMP int __cdecl _strcmpi(const char *, const char *); _CRTIMP int __cdecl _stricmp(const char *, const char *); _CRTIMP int __cdecl strcoll(const char *, const char *); _CRTIMP int __cdecl _stricoll(const char *, const char *); _CRTIMP int __cdecl _strncoll(const char *, const char *, size_t); _CRTIMP int __cdecl _strnicoll(const char *, const char *, size_t); _CRTIMP size_t __cdecl strcspn(const char *, const char *); _CRTIMP char * __cdecl _strdup(const char *); _CRTIMP char * __cdecl _strerror(const char *); _CRTIMP char * __cdecl strerror(int); _CRTIMP char * __cdecl _strlwr(char *); _CRTIMP char * __cdecl strncat(char *, const char *, size_t); _CRTIMP int __cdecl strncmp(const char *, const char *, size_t); _CRTIMP int __cdecl _strnicmp(const char *, const char *, size_t); _CRTIMP char * __cdecl strncpy(char *, const char *, size_t); _CRTIMP char * __cdecl _strnset(char *, int, size_t); _CRTIMP char * __cdecl strpbrk(const char *, const char *); _CRTIMP char * __cdecl strrchr(const char *, int); _CRTIMP char * __cdecl _strrev(char *); _CRTIMP size_t __cdecl strspn(const char *, const char *); _CRTIMP char * __cdecl strstr(const char *, const char *); _CRTIMP char * __cdecl strtok(char *, const char *); _CRTIMP char * __cdecl _strupr(char *); _CRTIMP size_t __cdecl strxfrm (char *, const char *, size_t); #ifdef _MAC unsigned char * __cdecl _c2pstr(char *); char * __cdecl _p2cstr(unsigned char *); #if !__STDC__ __inline unsigned char * __cdecl c2pstr(char *sz) { return _c2pstr(sz);}; __inline char * __cdecl p2cstr(unsigned char *sz) { return _p2cstr(sz);}; #endif #endif #if !__STDC__ /* prototypes for oldnames.lib functions */ _CRTIMP void * __cdecl memccpy(void *, const void *, int, unsigned int); _CRTIMP int __cdecl memicmp(const void *, const void *, unsigned int); _CRTIMP int __cdecl strcmpi(const char *, const char *); _CRTIMP int __cdecl stricmp(const char *, const char *); _CRTIMP char * __cdecl strdup(const char *); _CRTIMP char * __cdecl strlwr(char *); _CRTIMP int __cdecl strnicmp(const char *, const char *, size_t); _CRTIMP char * __cdecl strnset(char *, int, size_t); _CRTIMP char * __cdecl strrev(char *); char * __cdecl strset(char *, int); _CRTIMP char * __cdecl strupr(char *); #endif /* !__STDC__ */ #ifndef _MAC #ifndef _WSTRING_DEFINED /* wide function prototypes, also declared in wchar.h */ _CRTIMP wchar_t * __cdecl wcscat(wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl wcschr(const wchar_t *, wchar_t); _CRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl wcscpy(wchar_t *, const wchar_t *); _CRTIMP size_t __cdecl wcscspn(const wchar_t *, const wchar_t *); _CRTIMP size_t __cdecl wcslen(const wchar_t *); _CRTIMP wchar_t * __cdecl wcsncat(wchar_t *, const wchar_t *, size_t); _CRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t); _CRTIMP wchar_t * __cdecl wcsncpy(wchar_t *, const wchar_t *, size_t); _CRTIMP wchar_t * __cdecl wcspbrk(const wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl wcsrchr(const wchar_t *, wchar_t); _CRTIMP size_t __cdecl wcsspn(const wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl wcsstr(const wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl wcstok(wchar_t *, const wchar_t *); _CRTIMP wchar_t * __cdecl _wcsdup(const wchar_t *); _CRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *); _CRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t); _CRTIMP wchar_t * __cdecl _wcsnset(wchar_t *, wchar_t, size_t); _CRTIMP wchar_t * __cdecl _wcsrev(wchar_t *); _CRTIMP wchar_t * __cdecl _wcsset(wchar_t *, wchar_t); _CRTIMP wchar_t * __cdecl _wcslwr(wchar_t *); _CRTIMP wchar_t * __cdecl _wcsupr(wchar_t *); _CRTIMP size_t __cdecl wcsxfrm(wchar_t *, const wchar_t *, size_t); _CRTIMP int __cdecl wcscoll(const wchar_t *, const wchar_t *); _CRTIMP int __cdecl _wcsicoll(const wchar_t *, const wchar_t *); _CRTIMP int __cdecl _wcsncoll(const wchar_t *, const wchar_t *, size_t); _CRTIMP int __cdecl _wcsnicoll(const wchar_t *, const wchar_t *, size_t); #if !__STDC__ /* old names */ #define wcswcs wcsstr /* prototypes for oldnames.lib functions */ _CRTIMP wchar_t * __cdecl wcsdup(const wchar_t *); _CRTIMP int __cdecl wcsicmp(const wchar_t *, const wchar_t *); _CRTIMP int __cdecl wcsnicmp(const wchar_t *, const wchar_t *, size_t); _CRTIMP wchar_t * __cdecl wcsnset(wchar_t *, wchar_t, size_t); _CRTIMP wchar_t * __cdecl wcsrev(wchar_t *); _CRTIMP wchar_t * __cdecl wcsset(wchar_t *, wchar_t); _CRTIMP wchar_t * __cdecl wcslwr(wchar_t *); _CRTIMP wchar_t * __cdecl wcsupr(wchar_t *); _CRTIMP int __cdecl wcsicoll(const wchar_t *, const wchar_t *); #endif /* !__STDC__ */ #define _WSTRING_DEFINED #endif #endif /* ndef _MAC */ #ifdef __cplusplus } #endif #endif /* _INC_STRING */