C++复习之实现标准库的字符串操作函数
strcpy 、 strncpy 、 memmove 、 memcpy 、 memset 、 strlen 、 strncat 、 strcmp 、 strncmp 、 strstr 、 strchr 的实现
// The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buf
// pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive
//copy.
char *strcpy(char *dest, const char *src)
{
assert((src != NULL) && (dest != NULL));
size_t i;
for (i = 0; src[i] != '\0'; i++)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
// The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte am
the first n bytes of src,
// the string placed in dest will not be null-terminated. If the length of src is less than n, strncpy() pads the remainde
dest with null bytes.
char *strncpy(char *dest, const char *src, size_t n)
{
assert((src != NULL) && (dest != NULL));
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}
/* 在 32 位的 x86 平台上 , 每次拷贝 1 个字节需要一条指令 , 每次拷贝 4 个字节也只需要一条指
* 令 ,memcpy 函数的实现尽可能 4 个字节 4 个字节地拷贝 */
void *memcpy(void *dest, const void *src, size_t n) {
assert((src != NULL) && (dest != NULL));
char *d = dest;
const char *s = src;
int *di;
const int *si;
int r = n % 4;
while (r--)
*d++ = *s++;
di = (int *) d;
si = (const int *) s;
n /= 4;
while (n--)
*di++ = *si++;
return dest;
}
/* 借助于一个临时缓冲区 temp , 即使 src 和 dest 所指的内存区间有重叠也能正确拷贝。 */
void *memmove(void *dest, const void *src, size_t n) {
assert((src != NULL) && (dest != NULL));
char *temp = (char *) malloc(sizeof(char) * n);
size_t i;
char *d = (char *) dest;
const char *s = (const char *) src;
for (i = 0; i < n; i++)
temp[i] = s[i];
for (i = 0; i < n; i++)
d[i] = temp[i];
free(temp);
return dest;
}
size_t strlen(const char *p) {
assert(p != NULL);
size_t size = 0;
while (*p++ != '\0')
++size;
return size;
}
char *strncat(char *dest, const char *src, size_t n) {
size_t dest_len = strlen(dest);
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}
不用临时空间的 memmove 实现:
//src 可以不保留
void *memmove(void *dst, const void *src, size_t count) {
byte *pbTo = (byte *) dst;
byte *pbFrom = (byte *) src;
assert(dst != NULL && src != NULL); // 不能存在空指针
if (dst <= src || pbTo >= pbFrom + count) //
{
while (count-- > 0) {
*pbTo++ = *pbFrom++; // 按递增拷贝
}
} else //
{
pbTo = pbTo + count - 1; //overlap 的情况,从高位地址向低位拷贝
pbFrom = pbFrom + count - 1;
while (count-- > 0) {
*pbTo-- = *pbFrom--; // 按递减拷贝
}
}
return dst;
}
memset 的实现 :
void *memset(void *buffer, int c, int count) {
char *buffer_p = (char *) buffer;
assert(buffer != NULL);
while (count-- > 0)
*buffer_p++ = (char) c;
return buffer;
}
// 查找字符串 s 中首次出现字符 c 的位置
char *strchr(char *str, int c) {
assert(str != NULL);
for (; *str != (char) c; ++str)
if (*str == '\0')
return NULL;
return str;
}
// 字符串连接
char *strcat(char *strDes, const char *strSrc) {
assert((strDes != NULL) && (strSrc != NULL));
char *address = strDes;
while (*strDes != '\0')
++strDes;
while ((*strDes++ = *strSrc++) != '\0')
NULL;
*StrDes = '\0';
return address;
}
// 查找字符串第一次出现的位置
char *strstr(const char *strSrc, const char *str) {
assert(strSrc != NULL && str != NULL);
const char *s = strSrc;
const char *t = str;
for (; *strSrc != '\0'; ++strSrc) {
for (s = strSrc, t = str; *t != '\0' && *s == *t; ++s, ++t)
NULL;
if (*t == '\0')
return (char *) strSrc;
}
return NULL;
}
// 字符串比较
int strcmp(const char *s, const char *t) {
assert(s != NULL && t != NULL);
while (*s && *t && *s == *t) {
++s;
++t;
}
return (*s - *t);
}
int strncmp(const char *s, const char *t, int count) {
assert((s != NULL) && (t != NULL));
while (count-- > 0 && *s && *t && *s == *t) {
++s;
++t;
}
return (*s - *t);
}
请使用C语言完成strnicmp的编码实现,要求不能调用任何其它的函数。strcnicmp完成两个ascii字符串的比较,忽略大小写
(两个英文字母比较时,认为大小写无差别),最多比较n个字符(当两个字符串长度超过n时,就认为它们的长度都等于
n),返回<0表示第一个字符串小于第二个字符串,返回>0表示第一个字符串大于第二个字符串,返回等于0时表示两个字符
串相等。函数声明如下:int strnicmp(char const *s1, char const *s2, int n)
int strnicmp(char const *s1, char const *s2, int n) {
int i;
for (i = 0; i < n; i++) {
char a = s1[i], b = s2[i];
if (a >= 'A' && a <= 'Z')
a = a - 'A' + 'a';
if (b >= 'A' && b <= 'Z')
b = b - 'A' + 'a';
if (a == b)
continue;
return a - b;
}
return 0;
}