主要整理了字符串相关函数以及模拟实现:
1.求字符串长度:
strlen
2.长度不受限制的字符串函数:
strcpy
strcat
strcmp
3.长度受限制的字符串函数:
strncpy
strncat
strncmp
4.字符串查找:
strstr
strtok
5.错误信息报告:
strerror
1.strlen
size_t strlen(const char*str);
①返回在字符串中’\0’前面出现的字符个数;
②注意函数的返回值为size_t,是无符号的。
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* p)
{
assert(p != NULL);
int len=0;
while (*p != '\0')
{
len++;
p++;
}
return len;
}
int main()
{
const char* a = "abcd";
int len = my_strlen(a);
printf("len=%d\n", len);
return 0;
}
2.strcpy
char* strcpy(char *destination,const char * source);
①将源字符串赋给目标字符串,也会将’\0’赋过去;
②源字符串必须以’\0’结束;
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strcpy(char* strDest, const char* strSource)
{
assert(strDest != NULL && strSource != NULL);
char* pDest = strDest;
int str_len = strlen(strSource);
while (*strSource != '\0')
{
*pDest++ = *strSource++;
}
*pDest = '\0';
return strDest;
}
int main()
{
char a[6] = "abcdf";
char b[5] = "efgh";
my_strcpy(a, b);
printf("%s ", a);
return 0;
}
3.strcat
char* strcat(char *destination,const char *source);
字符串连接函数;
①源字符串必须以’\0’结束;
②连接时必须覆盖源字符串中的’\0’,否则会提前结束,连接不上;
#include<stdio.h>
#include<assert.h>
char* my_strcat( char* p, const char* q)
{
assert(p != NULL && q != NULL);
char* s = p;
while (*s != '\0')
{
s++;
}
while (*q != '\0')
{
*s++ = *q++;
}
*s = '\0';
return p;
}
int main()
{
char a[7] = "abc";
const char* b = "def";
my_strcat(a, b);
printf("%s\n",a );
return 0;
}
4.strcmp
int strcmp(const char *str1,const char *str2);
字符串比较函数
比较规则:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字。
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* string1, const char* string2)
{
assert(string1 != NULL && string2 != NULL);
int res = 0;
while (*string1!='\0'||*string2!='\0')
{
res = *string1 - *string2;
if (res != 0)
break;
string1++;
string2++;
}
if (res > 0)
res = 1;
else if (res < 0)
res = -1;
return res;
}
void main()
{
const char* str = "HealoC++";
const char* str1 = "Hello";
int res = my_strcmp(str,str1);
printf("res = %d\n", res);
}
5.strncpy
char* strncpy(char *destination,const char *source,size_t num);
拷贝num个字符从源字符串到目标空间;
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加0,直到num个。
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strncpy(char* strDest, const char* strSource, size_t count)
{
assert(strDest != NULL && strSource != NULL);
char* pDest = strDest;
int str_len = strlen(strSource);
for (int i = 0; i < count; ++i)
{
if (i < str_len)
*pDest++ = *strSource++;
else
*pDest++ = '\0';
}
return strDest;
}
int main()
{
char str[20] = "HelloC++";
const char* str1 = "Linux";
printf("str = %s\n", str);
my_strncpy(str, str1, 3);
//strncpy(str, str1, strlen(str1)+1);
//my_strncpy(str, str1, 3);
//char *ret = strncat(str, str1, 3);
printf("str = %s\n", str);
return 0;
}
6.strncat
将源字符串前num个字符连接到目标字符串。
char* strncat(char destination,const charsource,size_t num);
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strncat(char* strDest, const char* strSource, size_t count)
{
assert(strDest != NULL && strSource != NULL);
char* pDest = strDest;
while (*pDest != '\0')
pDest++;
int str_len = strlen(strSource);
for (int i = 0; i < str_len && i < count; ++i)
{
*pDest++ = *strSource++;
}
*pDest = '\0';
return strDest;
}
int main()
{
char str[20] = "HelloC++";
const char* str1 = "Linux";
printf("str = %s\n", str);
//strncpy(str, str1, 3);
//strncpy(str, str1, strlen(str1)+1);
//my_strncpy(str, str1, 3);
char *ret = my_strncat(str, str1, 3);
printf("str = %s\n", ret);
return 0;
}
7.strncmp
int strncmp(const char* str1,const char* str2,size_t num);
比较源字符串和目标字符串前num个字符
#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* string1, const char* string2, size_t count)
{
assert(string1 != NULL && string2 != NULL);
int res = 0;
while (count-- != 0)
{
res = *string1 - *string2;
if (res != 0)
break;
string1++;
string2++;
}
if (res > 0)
res = 1;
else if (res < 0)
res = -1;
return res;
}
int main()
{
const char* str = "HealoC++";
const char* str1 = "Hello";
int res = my_strncmp(str + 3, str1 + 3, 2);
printf("res = %d\n", res);
return 0;
}
8.strstr
char* strstr(const char*,const char*);
判断源字符串是否是目标字符串的子串,若是,则返回在目标字符串中的下标。
#include<stdio.h>
#include<assert.h>
#include<string.h>
int my_strstr(const char* string, const char* strCharSet)
{
assert(string != NULL && strCharSet != NULL);
int i, j;
i = j = 0;
int dest_len = strlen(string);
int charset_len = strlen(strCharSet);
while (i < dest_len - charset_len && j < charset_len)
{
if (strCharSet[j] == string[i])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j >= charset_len)
return i - j;
return -1;
}
void main()
{
//子串 模式匹配
const char* str1 = "abcabcababacccabc";
const char* str2 = "ababa";
int index = my_strstr(str1, str2);
printf("index = %d\n", index);
9.strtok
char* strtok(char* str,const char* sep);
①sep参数是个字符串,定义了用作分隔符的字符集合;
②第一个参数为待分割字符串;
③strtoc函数找到str的下一个标记,并将其用’\0’结尾,返回一个指向这个标记的指针;
④strtoc函数会改变被操作的字符串,所以在使用strtoc函数切分的字符串一般都是临时拷贝的内容并且可修改;
⑤strtoc函数的第一个参数不为NULL,函数将找到str中第一个标记,strtoc函数将保存它在字符串中的位置。
⑥strtoc函数为空,函数将在同一个字符串中被保存的位置开始,查找下一个标记;
⑦如果字符串中不存在更多的标记,则返回NULL指针。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "- This, a sample string.";
char* pch = strtok(str, " ,.-");
while (pch != NULL)
{
printf("%s\n", pch);
pch = strtok(NULL, " ,.-");
}
}
或:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
//char *p = "zhangpengwei\0qq.com";
char p[] = "zhangpengwei@163.com";
const char* sep = "@.";
strtok(p, sep);
char* res = strtok(NULL, sep);
printf("%s\n", res);
}
10.strerror
char* strerror(int errnum);
返回错误码所对应的错误信息。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main()
{
FILE* fp = fopen("Test1.txt", "r");
if (fp == NULL)
{
printf("errno = %d\n", errno);
printf("err msg = %s\n", strerror(errno));
printf("打开文件失败.\n");
return 0;
}
printf("打开文件成功.\n");
fclose(fp);
return 0;
}
以上打开文件以只读形式打开,而事先未创建文件,所以会发生错误,指针返回值为空,输出了错误码以及对应的错误信息。若以写入的形式打开,则不会报错,代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main()
{
FILE* fp = fopen("Test1.txt", "w");
if (fp == NULL)
{
printf("errno = %d\n", errno);
printf("err msg = %s\n", strerror(errno));
printf("打开文件失败.\n");
return 0;
}
printf("打开文件成功.\n");
fclose(fp);
return 0;
}