11.1求字符串长度
strlen
Get the length of a string.
size_t strlen( const char *string );
typedef unsigned int size_t;
strlen 返回值为 unsigned int
strlen返回字符串中 \0
前面出现的字符个数
参数指向的字符串必须要以\0
结束
int main() {
char arr[] = "hello ruarua";
printf("%u\n", strlen(arr));
return 0;
}
strlen simulation
//方案1.计数器
size_t my_strlen(const char* str){
int count = 0;
while (*str != '\0') {
count++;
str++;
}
return count;
}
//方案2.指针-指针
size_t my_strlen(const char* str) {
char* end = str;
while (*end != '\0')
end++;
return end - str;
}
//方案3.递归
size_t my_strlen(const char* str) {
if (*str == 0)
return 0;
else
return 1 + my_strlen(str + 1);
}
int main() {
int sz = my_strlen("ruarua");
printf("%u\n", sz);//%u unsigned int
return 0;
}
11.2长度不受限制的字符串函数
strcpy
Copy a string.
char *strcpy( char *strDestination, const char *strSource );
源字符串必须以\0
结束,\0
会拷贝到目标空间
目标空间必须足够大,以确保能存放源字符串
目标空间必须可修改
int main() {
char arr1[20] = { 0 };
char arr2[] = "hello ruarua";
//char arr2[] = {'r','u','a'};//没有'\0' err
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
strcpy simulation
#include <assert.h>
char* my_strcpy(char* dest, const char* src) {
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
while (*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = *src;//copy '\0'
return ret;
}
//简化-->
char* my_strcpy(char* dest, const char* src) {
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
while (*dest++ = *src++) {
;
}
return ret;
}
int main() {
char arr1[20] = { 0 };
char arr2[] = "hello ruarua";
printf("%s\n", my_strcpy(arr1, arr2));//链式访问
return 0;
}
strcat
Append a string.
char *strcat( char *strDestination, const char *strSource );
源字符串必须以 ‘\0’ 结束
目标空间必须有足够的大,能容纳下源字符串的内容
目标空间必须可修改
int main() {
char arr1[20] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
helloworld
strcat simulation
#include <assert.h>
char* my_strcat(char* dest, const char* src) {
assert(dest);
assert(src);
char* ret = dest;
//1.find dest's \0
while (*dest) {
dest++;
}
//2.copy
while (*dest++ = *src++) {
;
}
return ret;
}
int main() {
char arr1[20] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);//无法给自己追加,因为判断条件\0会被追加掉
return 0;
}
strcmp
Compare strings.
int strcmp( const char *string1, const char *string2 );
逐字符对比ASCII大小
str1 > str2, return > 0 返回大于0的数字
str1 = str2, return 0
str1 > str2, return < 0
int main() {
int ret = strcmp("abcdef", "abq");
printf("%d\n", ret);
return 0;
}
-1
strcmp simulation
int my_strcmp(const char* str1, const char* str2) {
while (*str1 == *str2) {
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2)
}
int main() {
int ret = my_strcmp("abcdef", "abq");
printf("%d\n", ret);
return 0;
}
11.3长度受限制的字符串函数
strncpy
Copy characters of one string to another.
char *strncpy( char *strDest, const char *strSource, size_t count );
拷贝num个字符从源到目标空间。
源长度小于num,拷贝源之后,在后边追加0到num个
int main() {
char arr1[20] = "abcdef";
char arr2[] = "xxxxxxxx";
strncpy(arr1, arr2, 3);
printf("%s\0", arr1);
return 0;
}
xxxdef
int main() {
char arr1[20] = "abcdef";
char arr2[] = "xxx";
strncpy(arr1, arr2, 6);
printf("%s\0", arr1);
return 0;
}
xxx
strncat
Append characters of a string.
char *strncat( char *strDest, const char *strSource, size_t count );
int main() {
char arr1[20] = "abcdef";
char arr2[] = "xxxxxxxx";
strncat(arr1, arr2, 5);
printf("%s\0", arr1);
return 0;
}
abcdefxxxxx
strncmp
Compare characters of two strings.
int strncmp( const char *string1, const char *string2, size_t count );
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
int main() {
char arr1[] = "abcdefg";
char arr2[] = "abcdxyz";
printf("%d\n", strncmp(arr1, arr2, 4));
return 0;
}
0
int main() {
char arr1[] = "abcdefg";
char arr2[] = "abcdxyz";
printf("%d\n", strncmp(arr1, arr2, 5));
return 0;
}
-1
11.4字符串查找
strstr
Find a substring.
char *strstr( const char *string, const char *strCharSet );
返回str1中str2字符首次出现的位置
找不到会返回空指针
int main() {
char arr1[] = "abcdefabcdef";
char arr2[] = "def";
char* ret = strstr(arr1, arr2);
if (*ret != NULL)
printf("%s", ret);
else
printf("Not Find");
return 0;
}
defabcdef
strstr simulation
char* my_strstr(const char* str1, const char* str2) {
char* cp = str1;
char* s1 = cp;
char* s2 = str2;
while (*cp) {//*cp != "\0"
//开始匹配
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2) {//s1,s2 != \0
s1++;
s2++;
}
if (*s2 == '\0')
return cp;
cp++;
}
return NULL;
}
int main() {
char arr1[] = "bbccnnnews";
char arr2[] = "cnn";
char* ret = my_strstr(arr1, arr2);
if (*ret != NULL)
printf("%s", ret);
else
printf("Not Find");
return 0;
}
ccnnnews
strtok
Find the next token in a string.
char *strtok( char *strToken, const char *strDelimit );
strDelimit:定界符: @ . --> char delimit[] = “@ .”;
strToken:由定界符分开的字符串:“192.168.1.1” ; “ruarua@mail.com”
strtok函数:找到str中下一个标记,将其置 ‘\0’ ,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)
- strToken不为 NULL ,函数将找到str中第一个标记,strtok函数保存它在字符串中的位置
- strToken为 NULL ,函数将在同一字符串中被保存的位置开始,查找下一个标记
- 如果字符串中不存在更多的标记,则返回 NULL 指针
int main() {
char arr[] = "ruarua\@mail.com";
char copy[20];
strcpy(copy, arr);
char sep[] = "@.";
char* ret = strtok(copy, sep);//找到str第一个标记,strtok保存在字符串中的位置
printf("%s\n", ret);
ret = strtok(NULL, sep);//函数将在被保存的位置开始,查找下一个标记
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
return 0;
}
int main() {
char arr[] = "ruarua\@mail.com";
char copy[20];
strcpy(copy, arr);
char sep[] = "@.";
char* ret = NULL;
for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL,sep)) {
printf("%s\n", ret);
}
return 0;
}
ruarua
mail
com
11.5错误信息报告
strerror
Get a system error message (strerror) or prints a user-supplied error message (_strerror).
char *strerror( int errnum );
库函数执行发生错误,将错误码存放在errno中,errno是C语言提供的一个全局变量
strerror返回errnum所对应的错误信息
int main() {
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d: %s\n",i, strerror(i));
}
return 0;
}
0: No error
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted function call
5: Input/output error
6: No such device or address
7: Arg list too long
8: Exec format error
9: Bad file descriptor
int main() {
//操作文件
//1.打开文件
//2.读/写
//3.关闭文件
FILE* pf = fopen("c.txt", "r");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
fclose(pf);//关闭文件
return 0;
}
No such file or directory
int main() {
FILE* pf = fopen("c.txt", "r");
if (pf == NULL) {
perror("fopen");//打印 自定义信息+错误信息
return 1;
}
fclose(pf);//关闭文件
return 0;
}
fopen: No such file or directory
11.6字符操作
字符分类函数
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母az或AZ |
isalnum | 字母或者数字,az,AZ,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
字符转换
int tolower ( int c );//转小写
int toupper ( int c );//转大写
#include <ctype.h>
int main() {
printf("%c\n", tolower('A'));//-->a
printf("%c\n", toupper('a'));//-->A
return 0;
}
int main() {
char arr[20] = { 0 };
gets(arr);//遇到空格继续读
printf("%s\n", arr);
char* p = arr;
while (*p) {
if (isupper(*p)) {
*p = tolower(*p);
}
p++;
}
printf("%s\n", arr);
return 0;
}
RUA RUA IS GOOD
RUA RUA IS GOOD
rua rua is good
11.7内存操作函数
memcpy
Copies characters between buffers.
void *memcpy( void *dest, const void *src, size_t count );
memcpy从source位置向后复制count个字节到destination内存位置
在遇到 ‘\0’ 时不会停下
source和destination有任何的重叠,复制的结果都是未定义的
拷贝完后返回目标空间其实地址
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
//将arr1拷贝到arr2
memcpy(arr2,arr1,40);
int i = 0;
for (i = 0; i < 20; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0
int main() {
float arr1[] = { 1.0,2.0,3.0 };
float arr2[5] = { 0 };
//将arr1拷贝到arr2
memcpy(arr2, arr1, 8);
int i = 0;
for (i = 0; i < 5; i++) {
printf("%f ", arr2[i]);
}
return 0;
}
1.000000 2.000000 0.000000 0.000000 0.000000
memcpy simulation
void* my_memcpy(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(src && dest);
while (num--) {
*(char*)dest = *(char*)src;//char* --> 1byte
dest = (char*)dest + 1;//dest is void*
src = (char*)src + 1;
}
return ret;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
//将arr1拷贝到arr2
my_memcpy(arr2,arr1,20);
int i = 0;
for (i = 0; i < 20; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
memmove
Moves one buffer to another.
void *memmove( void *dest, const void *src, size_t count );
和memcpy的差别:memmove函数处理的源内存块和目标内存块是可以重叠的
src和dest出现重叠,使用memmove函数
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//将arr1拷贝到arr1 + 3
memmove(arr1 + 3, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
1 2 3 1 2 3 4 5 9 10
memmove simulation
my_memmove(arr1 + 3, arr1, 20);
正序会覆盖重叠部分,逆序即可
my_memmove(arr1, arr1 + 3, 20);
但此情况逆序会覆盖掉src
故分两种情况
dest < src -->
src < dest <–
void* my_memmove(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(src && dest);
if (dest < src) {//-->
while (num--) {
*(char*)dest = *(char*)src;//char* --> 1byte
dest = (char*)dest + 1;//dest is void*
src = (char*)src + 1;
}
}
else {//<--
while (num--) {
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//将arr1拷贝到arr1 + 3
my_memmove(arr1 + 3, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
1 2 3 1 2 3 4 5 9 10
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//将arr1+ 3 拷贝到arr1
my_memmove(arr1, arr1 + 3, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
4 5 6 7 8 6 7 8 9 10
memset
Sets buffers to a specified character.
void *memset( void *dest, int c, size_t count );
内存设置:将dest前count个字节设置成指定的character
int main() {
char arr[] = "ruarua";
memset(arr, 'x', 3);//3 byte
printf("%s\n", arr);
return 0;
}
xxxrua
int main() {
int arr[10] = { 0 };
memset(arr, 1, 10);//10 byte --> 1,以字节为单位,将前10个字节变成1
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
16843009 16843009 257 0 0 0 0 0 0 0
memcmp
Compare characters in two buffers.
int memcmp( const void *buf1, const void *buf2, size_t count );
比较从buf1和buf2指针开始的count个字节
int main() {
int arr1[] = { 1,2,3,4,5,6 };
int arr2[] = { 1,2,3,4,100 };
int ret = memcmp(arr1, arr2, 20);
printf("%d\n", ret);
return 0;
}
-1