C标准库<string.h>实现
本文地址:http://www.cnblogs.com/archimedes/p/c-library-string.html,转载请注明源地址。
1.背景知识
<string.h>中声明的函数是对标准C的一个重要补充,它们支持C语言把文本作为字符数组操作的传统。
string.h是C语言中C标准库的头文件,其中包含了宏定义、常量以及函数和类型的声明,涉及的内容除了字符串处理之外,还包括大量的内存处理函数;因此,string.h这个命名是不恰当的。在string.h中定义的函数十分常用,作为C标准库的一部分,它们被强制要求可以在任何支持C语言的平台上运行。但是,部分函数存在一些安全隐患,例如缓存溢出等,导致程序员宁愿使用一些更安全的函数而放弃一定的可移植性。同时,这些字符串函数只能处理ASCII字符集或兼容ASCII的字符集,如ISO-8859-1;在处理存在多字节字符的字符集,如UTF-8时,会产生一个警告,指出对字符串“长度”的计算是以字节而不是以Unicode字符为单位。非ASCII兼容字符集的字符串处理函数一般位于wchar.h中。
C标准库提供了所有重要的功能。这些函数可以对一下3种形式的串进行操作:
名字以mem开头的函数对任意的字符序列进行操作
名字以strn开头的函数对非空字符序列进行操作
所有其他名字以str开头的函数对空字符结尾的字符序列进行操作
2.<string.h>的内容
常量和类型
| 名称 | 说明 |
|---|---|
NULL |
表示空指针常量的宏,即表示一个不指向任何有效内存单元地址的指针常量。 |
size_t |
无符号整型,被用于sizeof运算符的返回值类型。 |
代码如下:
#ifndef _STRING_H
#define _STRING_H
#define NULL ((void *)0)
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t; /* type returned by sizeof */
#endif /*_SIZE_T */
函数
| 名称 | 说明 |
|---|---|
void *memcpy(void *dest, const void *src, size_t n); |
将n字节长的内容从一个内存地址复制到另一个地址;如果两个地址存在重叠,则最终行为未定义 |
void *memmove(void *dest, const void *src, size_t n); |
将n字节长的内容从一个内存地址复制到另一个地址;与memcpy不同的是它可以正确作用于两个存在重叠的地址 |
void *memchr(const void *s, char c, size_t n); |
在从s开始的n个字节内查找c第一次出现的地址并返回,若未找到则返回NULL |
int memcmp(const void *s1, const void *s2, size_t n); |
对从两个内存地址开始的n个字符进行比较 |
void *memset(void *, int, size_t); |
用某种字节内容覆写一段内存空间 |
char *strcat(char *dest, const char *src); |
在字符串dest之后连接上src |
char *strncat(char *dest, const char *src, size_t n); |
在字符串dest之后连接上src,最多增加n个字符 |
char *strchr(const char *, int); |
从字符串头开始查找某字符出现的位置 |
char *strrchr(const char *, int); |
从字符串尾开始查找某字符出现的位置 |
int strcmp(const char *, const char *); |
基于字典顺序比较两个字符串 |
int strncmp(const char *, const char *, size_t); |
基于字典顺序比较两个字符串,最多比较n个字节 |
int strcoll(const char *, const char *); |
基于当前区域设置的字符顺序比较两个字符串 |
char *strcpy(char *toHere, const char *fromHere); |
将一个字符串从一个位置复制到另一个位置 |
char *strncpy(char *toHere, const char *fromHere, size_t); |
将一个字符串从一个位置复制到另一个位置,最多复制n个字节 |
char *strerror(int); |
返回错误码对应的解释字符串,参见errno.h(非线程安全函数) |
size_t strlen(const char *); |
返回一个字符串的长度 |
size_t strspn(const char *s, const char *strCharSet); |
从字符串s的起始处开始,寻找第一个不出现在strCharSet中的字符,返回其位置索引值 |
size_t strcspn(const char *s, const char *strCharSet); |
从字符串s的起始处开始,寻找第一个出现在strCharSet中的字符,返回其位置索引值 |
char *strpbrk(const char *s, const char *strCharSet); |
在字符串s中查找strCharSet中任意字符第一次出现的位置的指针值 |
char *strstr(const char *haystack, const char *needle); |
在字符串haystack中查找字符串needle第一次出现的位置,heystack的长度必须长于needle |
char *strtok(char *, const char *); |
将一个字符串分隔成一系列字符串;此函数非线程安全,且不可重入 |
size_t strxfrm(char *dest, const char *src, size_t n); |
根据当前locale转换一个字符串为strcmp使用的内部格式 |
函数原型代码如下:
void *memchr(const void *_s, int _c, size_t _n);
int memcmp(const void *_s1, const void *_s2, size_t _n);
void *memcpy(void *_s1, const void *_s2, size_t _n);
void *memmove(void *_s1, const void *_s2, size_t _n);
void *memset(void *_s, int _c, size_t _n);
char *strcat(char *_s1, const char *_s2);
char *strchr(const char *_s, int _c);
int strncmp(const char *_s1, const char *_s2, size_t _n);
int strcmp(const char *_s1, const char *_s2);
int strcoll(const char *_s1, const char *_s2);
char *strcpy(char *_s1, const char *_s2);
size_t strcspn(const char *_s1, const char *_s2);
char *strerror(int _errnum);
size_t strlen(const char *_s);
char *strncat(char *_s1, const char *_s2, size_t _n);
char *strncpy(char *_s1, const char *_s2, size_t _n);
char *strpbrk(const char *_s1, const char *_s2);
char *strrchr(const char *_s, int _c);
size_t strspn(const char *_s1, const char *_s2);
char *strstr(const char *_s1, const char *_s2);
char *strtok(char *_s1, const char *_s2);
size_t strxfrm(char *_s1, const char *_s2, size_t _n);
3.<string.h>的实现
void * memcpy(void *s1, const void *s2, register size_t n)
{
register char *p1 = s1;
register const char *p2 = s2; if (n) {
n++;
while (--n > ) {
*p1++ = *p2++;
}
}
return s1;
}
memcpy
2、void *memmove( void* dest, const void* src, size_t count );
功能:由src所指内存区域复制count个字节到dest所指内存区域
返回:函数返回指向dest的指针
void * memmove(void *s1, const void *s2, register size_t n)
{
register char *p1 = s1;
register const char *p2 = s2;
if (n>) {
if (p2 <= p1 && p2 + n > p1) {
/* overlap, copy backwards */
p1 += n;
p2 += n;
n++;
while (--n > ) {
*--p1 = *--p2;
}
} else {
n++;
while (--n > ) {
*p1++ = *p2++;
}
}
}
return s1;
}
memmove
3、void *memchr(const void *buf, int ch, size_t count);
void *memchr(const void *s, register int c, register size_t n)
{
register const unsigned char *s1 = s;
c = (unsigned char) c;
if (n) {
n++;
while (--n > ) {
if (*s1++ != c) continue;
return (void *) --s1;
}
}
return NULL;
}
memchr
4、int memcmp(const void *buf1, const void *buf2, unsigned int count);
int memcmp(const void *s1, const void *s2, size_t n)
{
register const unsigned char *p1 = s1, *p2 = s2;
if (n) {
n++;
while (--n > ) {
if (*p1++ == *p2++) continue;
return *--p1 - *--p2;
}
}
return ;
}
memcmp
void *memset(void *s, register int c, register size_t n)
{
register char *s1 = s; if (n>) {
n++;
while (--n > ) {
*s1++ = c;
}
}
return s;
}
memset
6、char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
char *strcat(char *ret, register const char *s2)
{
register char *s1 = ret;
while (*s1++ != '\0')
/* EMPTY */ ;
s1--;
while (*s1++ = *s2++)
/* EMPTY */ ;
return ret;
}
strcat
7、char *strncat(char * s1,const char * s2.size_t n);
char *strncat(char *ret, register const char *s2, size_t n)
{
register char *s1 = ret; if (n > ) {
while (*s1++)
/* EMPTY */ ;
s1--;
while (*s1++ = *s2++) {
if (--n > ) continue;
*s1 = '\0';
break;
}
return ret;
} else return s1;
}
strncat
8、char *strchr(const char *s,char c);
功能:查找字符串s中首次出现字符c的位置
char *strchr(register const char *s, register int c)
{
c = (char) c; while (c != *s) {
if (*s++ == '\0') return NULL;
}
return (char *)s;
}
strchr
9、char *strrchr(const char *s, int c)
char *strrchr(register const char *s, int c)
{
register const char *result = NULL; c = (char) c; do {
if (c == *s)
result = s;
} while (*s++ != '\0'); return (char *)result;
}
strrchr
10、int strcmp(const char *s1,const char * s2);
功能:比较两个字符串。设这两个字符串为str1,str2,若str1=str2,则返回零;若str1>str2,则返回正数;若str1<str2,则返回负数。
int strcmp(register const char *s1, register const char *s2)
{
while (*s1 == *s2++) {
if (*s1++ == '\0') {
return ;
}
}
if (*s1 == '\0') return -;
if (*--s2 == '\0') return ;
return (unsigned char) *s1 - (unsigned char) *s2;
}
strcmp
11、int strncmp(char *str1, char *str2, int maxlen);
int strncmp(register const char *s1, register const char *s2, register size_t n)
{
if (n) {
do {
if (*s1 != *s2++)
break;
if (*s1++ == '\0')
return ;
} while (--n > );
if (n > ) {
if (*s1 == '\0') return -;
if (*--s2 == '\0') return ;
return (unsigned char) *s1 - (unsigned char) *s2;
}
}
return ;
}
strncmp
12、int strcoll(const char *s1,const char * s2);
功能:根据LC_COLLATE比较字符串s1和s2
int strcoll(register const char *s1, register const char *s2)
{
while (*s1 == *s2++) {
if (*s1++ == '\0') {
return ;
}
}
return *s1 - *--s2;
}
strcoll
13、char *strcpy(char* dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
char *strcpy(char *ret, register const char *s2)
{
register char *s1 = ret; while (*s1++ = *s2++)
/* EMPTY */ ; return ret;
}
strcpy
14、char *strncpy(char *_s1, const char *_s2, size_t _n);
功能:(c/c++)复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_t的值决定,返回指向dest的指针。如果遇到空字符('\0'),则空字符后面全部为空(字符)
char *strncpy(char *ret, register const char *s2, register size_t n)
{
register char *s1 = ret; if (n>) {
while((*s1++ = *s2++) && --n > )
/* EMPTY */ ;
if ((*--s2 == '\0') && --n > ) {
do {
*s1++ = '\0';
} while(--n > );
}
}
return ret;
}
strncpy
15、char *strerror(int errnum)
功能:通过标准错误的标号,获得错误的描述字符串。
char *strerror(register int errnum)
{
extern const char *_sys_errlist[];
extern const int _sys_nerr; if (errnum < || errnum >= _sys_nerr)
return "unknown error";
return (char *)_sys_errlist[errnum];
}
strerror
16、size_t strlen(const char *org)
size_t strlen(const char *org)
{
register const char *s = org; while (*s++)
/* EMPTY */ ; return --s - org;
}
strlen
17、size_t strspn (const char *s,const char * accept);
功能:strspn()从参数s 字符串的开头计算连续的字符,而这些字符都完全是accept 所指字符串中的字符。简单的说,若strspn()返回的数值为n,则代表字符串s 开头连续有n 个字符都是属于字符串accept内的字符
size_t strspn(const char *string, const char *in)
{
register const char *s1, *s2; for (s1 = string; *s1; s1++) {
for (s2 = in; *s2 && *s2 != *s1; s2++)
/* EMPTY */ ;
if (*s2 == '\0')
break;
}
return s1 - string;
}
strspn
18、size_t strcspn(const char *string, const char *notin)
功能:顺序在字符串s1中搜寻与s2中字符的第一个相同字符,返回这个字符在S1中第一次出现的位置
size_t strcspn(const char *string, const char *notin)
{
register const char *s1, *s2; for (s1 = string; *s1; s1++) {
for(s2 = notin; *s2 != *s1 && *s2; s2++)
/* EMPTY */ ;
if (*s2)
break;
}
return s1 - string;
}
strcspn
19、char *strpbrk(const char *s1, const char *s2);
功能:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内
char *strpbrk(register const char *string, register const char *brk)
{
register const char *s1; while (*string) {
for (s1 = brk; *s1 && *s1 != *string; s1++)
/* EMPTY */ ;
if (*s1)
return (char *)string;
string++;
}
return (char *)NULL;
}
strpbrk
20、char *strstr(const char *str1, const char *str2);
char *strstr(register const char *s, register const char *wanted)
{
register const size_t len = strlen(wanted); if (len == ) return (char *)s;
while (*s != *wanted || strncmp(s, wanted, len))
if (*s++ == '\0')
return (char *)NULL;
return (char *)s;
}
strstr
21、char *strtok(char *string, const char *separators)
char *strtok(register char *string, const char *separators)
{
register char *s1, *s2;
static char *savestring; if (string == NULL) {
string = savestring;
if (string == NULL) return (char *)NULL;
} s1 = string + strspn(string, separators);
if (*s1 == '\0') {
savestring = NULL;
return (char *)NULL;
} s2 = strpbrk(s1, separators);
if (s2 != NULL)
*s2++ = '\0';
savestring = s2;
return s1;
}
strtok
22、size_t strxfrm(char *s1, const char *save, size_t n)
功能:根据num长度拷贝前num个字符到目的字符串中,并返回源字符串长度。同时,该函数还可以自作为返回字符串长度,这时num=0,destination允许传入NULL
size_t strxfrm(register char *s1, register const char *save, register size_t n)
{
register const char *s2 = save; while (*s2) {
if (n > ) {
n--;
*s1++ = *s2++;
} else
s2++;
}
if (n > )
*s1++ = '\0';
return s2 - save;
}
strxfrm
C标准库<string.h>实现的更多相关文章
- C 标准库 - ctype.h
C 标准库 - ctype.h This header declares a set of functions to classify and transform individual charact ...
- C标准库<ctype.h>实现
本文地址:http://www.cnblogs.com/archimedes/p/c-library-ctype.html,转载请注明源地址. 1.背景知识 ctype.h是C标准函数库中的头文件,定 ...
- C 标准库 - ctype.h之iscntrl 使用
iscntrl int iscntrl ( int c ); Check if character is a control character 检查给定字符是否为控制字符,即编码 0x00-0x1F ...
- C 标准库 - ctype.h之isalpha使用
isalpha int isalpha ( int c ); Checks whether c is an alphabetic letter. 检查给定字符是否字母字符,即是大写字母( ABCDEF ...
- C 标准库 - ctype.h之isalnum使用
isalnum int isalnum ( int c ); Checks whether c is either a decimal digit or an uppercase or lowerca ...
- C 标准库 - string.h
C 标准库 - string.h This header file defines several functions to manipulate C strings and arrays. stri ...
- C 标准库 - <assert.h>
C 标准库 - <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 a ...
- C 标准库 - <stdarg.h>
C 标准库 - <stdarg.h> 简介 stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数. 可变参 ...
- C 标准库 - <signal.h>
C 标准库 - <signal.h> 简介 signal.h 头文件定义了一个变量类型 sig_atomic_t.两个函数调用和一些宏来处理程序执行期间报告的不同信号. 库变量 下面是头文 ...
- C 标准库 - <setjmp.h>
C 标准库 - <setjmp.h> 简介 setjmp.h 头文件定义了宏 setjmp().函数 longjmp() 和变量类型 jmp_buf,该变量类型会绕过正常的函数调用和返回规 ...
随机推荐
- 自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
关于 MongoDB,下面来自百度百科: MongoDB[1]是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. mongoDB[1] Mon ...
- ruby -- 基础学习(八)中文字符串截取的函数
学习来源:http://www.codesky.net/article/200910/166595.html truncate(text, length = 30, truncate_string = ...
- 创意设计展示:折叠效果在移动 App 中的应用
在今天在移动 App 界面设计中,你可以看到不同创意类型的视觉效果.特别是在 Dribbble 上面,有有很多应用程序的 UI 概念设计,让你惊叹.当然,他们大多只是作为一个概念设计,可能永远也不会成 ...
- Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果
在页面中引入 Pace.js 和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接到任何代码,自动检测进展.您可以选择颜色和多种效果,有简约,闪光灯, ...
- HT图形组件设计之道(三)
上篇我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动,这类案例后续文章还会继续以便大家掌握更多的矢量应用场景,本篇我们先切换个话题, ...
- 转载---QRcodeJS生成二维码
QRCode.js QRCode.js是依赖JS生成二维码的.主要是通过获取DOM的标签,再通过HTML5Canvas绘制而成,不依赖JQ 获取QRCode.js Github-Page:qrcode ...
- Struts2文件上传(基于表单的文件上传)
•Commons-FileUpload组件 –Commons是Apache开放源代码组织的一个Java子项目,其中的FileUpload是用来处理HTTP文件上传的子项目 •Commons-Fil ...
- JS代码放置位置、变量与数据类型、运算符与逻辑表达运算符
内容简要: 1.JS代码放置位置的问题: 2.变量与数据类型: 3.运算符与逻辑表达式的运算符 我的位置 全局问题:为何在网页推荐位置(一般在<head></head>内部 ...
- SqlDataReader、SqlDataAdapter與SqlCommand的 区别
1.SqlDataReader,在线应用,需要conn.open(),使用完之后要关闭. SqlConnection conn = new SqlConnection(connStr); //conn ...
- Microsoft Excel软件打开文件出现文件的格式与文件扩展名指定格式不一致?
今天winform代码做一个datagridview数据导出功能,导出的excel文件的后缀是*.xls(Micorsoft Excel 2000), 而本机新建的excel文件的后缀是 *.xlsx ...