用户名: 密码: 忘记密码? 注册

字符串基本操作集锦【转】

作者:  时间: 2010-12-28

字符串基本操作集锦

所有C语言标准库支持的字符串操作都在string.h中,这个文件在/usr/include/下。确切的说,这个文件还包含对数组的访问。所包含的函数分为以下几类:复制、连接、比较、查找等。

1 复制

void * memcpy ( void * destination, const void * source, size_t num );
void * memmove ( void * destination, const void * source, size_t num );
char * strcpy ( char * destination, const char * source );
char * strncpy ( char * destination, const char * source, size_t num );
  • memcpy:从source处拷贝num字节的数据到destination。
  • memmove: 和memcpy一样。但当source和destination出现内存区域重叠时,也能正确处理。
  • strcpy: 从source处将字符串拷贝到destination处,拷贝过程一直持续到source中null字符为止。
  • strncpy: 从source处拷贝num个字符到destination处。若在拷贝过程中source中有null字符,destination使用0补齐到num个字符处。

2 连接

char * strcat ( char * destination, const char * source );
char * strncat ( char * destination, char * source, size_t num );
  • strcat: 把source传复制并连接到destination后,destination串结尾处的null字符将被source的第一个字符覆盖。source串的某尾处将被添加新的null字符。返回destiination串的指针。
  • strncat: 把source的前num个字符复制禀连接到destination后,关于null的操作和strcat相同。

3 比较

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
int strcmp ( const char * str1, const char * str2 );
int strcoll ( const char * str1, const char * str2 );
int strncmp ( const char * str1, const char * str2, size_t num );
size_t strxfrm ( char * destination, const char * source, size_t num );
  • memcmp:比较ptr1和ptr2的前num个字节。若二者相等,返回0;否则返回ptr1和ptr2中第一个不相等字节的比较结果。
  • strcmp:比较字符串ptr1和ptr2。若二者长度和字符都相等,返回0;否则返回ptr1和ptr2中第一个不相等字符的比较结果。
  • strcoll: 根据LCCOLLATE指定的文字排序规则次序比较str1和str2,在LCCOLLATE为“POSIX”或“C”时,strcoll和strcmp作用完全相同
  • strncmp:比较ptr1和ptr2的前num个字符。若二者相等,返回0;否则返回ptr1和ptr2中第一个不相等字符的比较结果。
  • strxfrm:字符串转换。从source中转换num个字符到destination中,使得strxfrm()转换后,strcmp的结果和直接使用strcoll的结果相同。

4 查找

const void * memchr ( const void * ptr, int value, size_t num );
const char * strchr ( const char * str, int character );
size_t strcspn ( const char * str1, const char * str2 );
const char * strpbrk ( const char * str1, const char * str2 );
const char * strrchr ( const char * str, int character );
size_t strspn ( const char * str1, const char * str2 );
const char * strstr ( const char * str1, const char * str2 );
char * strtok ( char * str, const char * delimiters );
  • memchr: 在ptr指向的num个存储空间内查找第一个值为value的字节,并返回指向它的指针。
  • strchr: 查找str指向字符串中第一个字符为character的位置,返回指向该位置的指针。
  • strcspn: 扫描str1字符串,找到首次出现任意str2中字符的位置,返回str1中这个位置前的字符个数。
  • strpbrk: 扫描str1字符串,找到首次出现任意str2中字符的位置,返回指向该位置的指针,如找不到,返回NULL。
  • strrchr:查找str指向字符串中最后一个字符为character的位置,返回指向该位置的指针。
  • strspn: 找出str1中从第一次出现str2中字符开始,连续出现str2中字符的长度,返回该长度。
  • strstr: 找出str2中第一次出现str1的位置,返回指向该为止的指针,若不含有,返回NULL。
  • strtok: 用法很诡异的一个函数。如下例子。这个函数用于分割字符串,需要循环调用完成分割。循环调用时,传入的字符串为NULL。很好奇这个函数如何实现的:)
    /* strtok example */
    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    char str[] ="- This, a sample string.";
    char * pch;
    printf ("Splitting string \"%s\" into tokens:\n",str);
    pch = strtok (str," ,.-");
    while (pch != NULL)
    {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
    }
    return 0;
    }

5 其他函数

void * memset ( void * ptr, int value, size_t num );
char * strerror ( int errnum );
size_t strlen ( const char * str );
  • memset:从ptr开始,把连续num个字节的内存设置为值value,返回ptr
  • strerror: 根据errum,返回一个静态的字符串,这个字符串可以是一些错误提示,都是字符串常量。
  • strlen: 返回字符串str的长度。长度通过NULL字符来定位。

6 strtok函数的实现

函数strtok很有趣,通过上面的例子可以看到这个函数自身会记录一些变量信息,供下次被调用时使用。记录在哪里?怎么就记录了呢?下面是在glibc中strtok最简单的实现方式.原来只是个全局变量而已:) 有意思。

static char *olds;

/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
char s[] = "-abc-=-def";
x = strtok(s, "-"); // x = "abc"
x = strtok(NULL, "-="); // x = "def"
x = strtok(NULL, "="); // x = NULL
// s = "abc\0=-def\0"
*/
char *
strtok (s, delim)
char *s;
const char *delim;
{
char *token;

if (s == NULL)
s = olds;

/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
{
olds = s;
return NULL;
}

/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);
if (s == NULL)
/* This token finishes the string. */
olds = __rawmemchr (token, '\0');
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}