/****************************************************************************************************************
* string function 字符串常用函数仿真
* Computer Science and Technology College of Shandong University. All Rights Reserved.
* Author: Guangcong Liu
****************************************************************************************************************
*/
#include <cassert>
#include <cstddef>
#include <iostream>
using std::cout;
using std::endl;
/****************************************************************************************************************
* The strlen() function returns the length of str
* (determined by the number of characters before null termination).
****************************************************************************************************************
*/
size_t strlen(const char* str)
{
assert(str != 0);
size_t len = 0;
while(*str++) len++;
return len;
}
/*****************************************************************************************************************
* The strcpy() function copies characters in the string "src" to the string "dest", including the null termination.
* The return value is dest.
* Note that strcpy() does not perform bounds checking, and thus risks overrunning from or to.
* For a similar (and safer) function that includes bounds checking, see strncpy().
*****************************************************************************************************************
*/
char* strcpy(char* dest, const char* src)
{
assert(dest != 0 && src != 0);
char* r = dest;
const char* t = src;
while(*r++ = *t++)
;
return dest;
}
/******************************************************************************************************************
* The strncpy() function copies at most count characters of 'src' to the string 'dest'.
* If src has less than count characters, the remainder is padded with '/0' characters.
* The return value is the resulting string.
******************************************************************************************************************
*/
char* strncpy(char *dest, const char *src, size_t n)
{
assert(dest && src);
char* r = dest;
const char* t = src;
for(size_t i = 0; i < n; i++)
{
if((*r++ = *t++) == 0)
{
while(++i < n)
{
*r++ = '/0';
}
return dest;
}
}//end for
return dest;
}
/******************************************************************************************************************
* The function strcmp() compares s1 and s2, then returns:
* Return value Explanation
* less than 0 s1 is less than s2
* equal to 0 s1 is equal to s2
* greater than 0 s1 is greater than s2
******************************************************************************************************************
*/
int strcmp(const char* s1, const char* s2)
{
assert(s1 && s2);
unsigned c1, c2;
for(;;)
{
c1 = *s1++;
c2 = *s2++;
if(c1 != c2) {
if(c1 > c2)
return 1;
return -1;
}
if(c1 == 0) //蕴含c2 == 0
return 0;
}//end for
}
/********************************************************************************************************************
* The strncmp() function compares at most count characters of s1 and s2. The return value is as follows:
* Return value Explanation
* less than 0 s1 is less than s2
* equal to 0 s1 is equal to s2
* greater than 0 s1 is greater than s2
* If there are less than count characters in either string,
* then the comparison will stop after the first null termination is encountered.
********************************************************************************************************************
*/
int strncmp(const char *s1, const char *s2, size_t n)
{
assert(s1 && s2);
unsigned c1, c2;
while(n > 0) {
c1 = *s1++;
c2 = *s2++;
n--;
if(c1 != c2) {
if(c1 > c2)
return 1;
return -1;
}
if(c1 == 0) //c1==0 => c2==0
break;
}
return 0;
}
/********************************************************************************************************************
* The function strchr() returns a pointer to the first occurrence of ch in str, or NULL if no match is found.
********************************************************************************************************************
*/
char* strchr(const char* str, int ch)
{
assert(str);
if(ch == 0)
{
while(*str++)
;
return (char*)--str;
}
while(*str)
if(*str++ == ch) return (char*)--str;
return 0;
}
/********************************************************************************************************************
* The function strrchr() returns a pointer to the last occurrence of ch in str, or NULL if no match is found.
********************************************************************************************************************
*/
char* strrchr(const char *str, int c)
{
assert(str);
if(c == 0)
return strchr(str, 0);
const char* r = 0;
while(str = strchr(str, c))
r = str++;
return (char*)r;
}
/********************************************************************************************************************
* The strcat() function concatenates str2 onto the end of str1, and returns str1.
* return strcpy(strchr(s1, 0), s2);
* Note that strcat() does not perform bounds checking, and thus risks overrunning str1 or str2.
********************************************************************************************************************
*/
char* strcat(char* first, const char* second)
{
assert(first && second);
char *r = first;
const char* t = second;
while(*r) r++;
while(*r++ = *t++);
return first;
}
/********************************************************************************************************************
* The function strstr() returns a pointer to the first occurrence of sub in str, or NULL if no match is found.
* If the length of sub is zero, then strstr () will simply return str.
********************************************************************************************************************
*/
char* strstr(const char *str, const char *sub)
{
assert(str && sub);
int first = sub[0];
if(first == 0)
return (char*)str;
size_t n = strlen(sub);
for(const char* r = strchr(str, first); r; r = strchr(r+1, first))
if(strncmp(r, sub, n) == 0)
return (char*)r;
return 0;
}
/********************************************************************************************************************
* The strspn() function returns the index of the first character in str1 that doesn't match any character in str2.
*
********************************************************************************************************************
*/
size_t strspn( const char *str1, const char *str2 )
{
//TODO
}
/********************************************************************************************************************
* The strspn() function returns the index of the first character in str1 that doesn't match any character in str2.
*
********************************************************************************************************************
*/
long atol(char *s)
{
long n;
int f;
n = 0;
f = 0;
//将指针移到第一个"数字",且控制正负号
while(*s == ' ' || *s == '/t')
s++;
if(*s == '-' || *s == '+') {
if(*s++ == '-')
f = 1;
while(*s == ' ' || *s == '/t')
s++;
}
if(s[0]=='0' && s[1])
{
//if 16进制
if(s[1]=='x' || s[1]=='X')
{
s += 2;
for(;;)
{
if(*s >= '0' && *s <= '9')
n = n*16 + *s++ - '0';
else if(*s >= 'a' && *s <= 'f')
n = n*16 + *s++ - 'a' + 10;
else if(*s >= 'A' && *s <= 'F')
n = n*16 + *s++ - 'A' + 10;
else
break;
}
} //end if 16进制
else //if 8进制
while(*s >= '0' && *s <= '7')
n = n*8 + *s++ - '0';
} else // if 10进制
while(*s >= '0' && *s <= '9')
n = n*10 + *s++ - '0';
if(f)
n = -n;
return n;
}
/********************************************************************************************************************
*The function toupper() returns the uppercase version of the character ch.
********************************************************************************************************************
*/
int toupper(int c)
{
if(c < 'a' || c > 'z')
return c;
return (c-'a'+'A');
}
/********************************************************************************************************************
*The function tolower() returns the lowercase version of the character ch.
********************************************************************************************************************
*/
int tolower(int c)
{
if(c < 'A' || c > 'Z')
return c;
return (c-'A'+'a');
}
/********************************************************************************************************************
* The function memcpy() copies count characters from the array srcaddr to the array destaddr.
* The return value of memcpy() is destaddr.
* The behavior of memcpy() is undefined if destaddr and srcaddr overlap.
********************************************************************************************************************
*/
void * memcpy (void *destaddr, void const *srcaddr, size_t len)
{
unsigned char *dest = (unsigned char*)destaddr;
const unsigned char *src = (const unsigned char*)srcaddr;
while (len-- > 0)
*dest++ = *src++;
return destaddr;
}
/********************************************************************************************************************
* The memmove() function is identical to memcpy(), except that it works even if destaddr and srcaddr overlap.
********************************************************************************************************************
*/
void * memmove (void *destaddr, void const *sourceaddr, size_t length)
{
unsigned char *dest = (unsigned char*)destaddr;
unsigned const char *source = (const unsigned char*)sourceaddr;
if (source < dest)
/* Moving from low mem to hi mem; start at end. */
for (source += length, dest += length; length; --length)
*--dest = *--source;
else if (source != dest)
{
/* Moving from hi mem to low mem; start at beginning. */
for (; length; --length)
*dest++ = *source++;
}
return destaddr;
}
/********************************************************************************************************************
* The function memcmp() compares the first count characters of buffer1 and buffer2. The return values are as follows:
* Value Explanation
* less than 0 buffer1 is less than buffer2
* equal to 0 buffer1 is equal to buffer2
* greater than 0 buffer1 is greater than buffer2
********************************************************************************************************************
*/
int memcmp(const void* str1, const void* str2, size_t count)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
while (count-- > 0)
{
if (*s1++ != *s2++)
return s1[-1] < s2[-1] ? -1 : 1;
}
return 0;
}
/********************************************************************************************************************
* The function memset() copies ch into the first count characters of buffer, and returns buffer.
* memset() is useful for intializing a section of memory to some value. For example, this command:
********************************************************************************************************************
*/
void * memset (void *str, int c, size_t len)
{
unsigned char *s = (unsigned char*)str;
while (len-- > 0)
*s++ = c;
return str;
}