- strlen(求字符串长度)
size_t strlen(const char *str)
<1>由于要求字符串的长度,因此字符串不可被修改,用const修饰;
<2>函数返回值为无符号数。
例:
#include<stdio.h>
#include<windows.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("str1>str2\n");
}
system("pause");
return 0;
}
运行结果:
其中(strlen(str2) - strlen(str1) > 0)条件永远成立。
2.01 strcpy(拷贝)
char* strcpy(char* destination,const char* source)
<1>目标空间必须足够大且可变,保证可以存放源字符串;
<2>源字符串以‘\0’结束,拷贝时也会将‘\0’拷贝至目标空间。
例:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
const char* str = "hello world";
char buff[32];
strcpy(buff, str);
printf("%s\n", buff);
system("pause");
return 0;
}
运行结果:
2.02 strncpy
char* strncpy(char* destination,const char* source,size_t num)
<1>拷贝num个字符从源字符串到目标空间;
<2>如果源字符串的长度小于num,则拷贝完源字符串后,给目标字符串的后面追加0,直到num个。
3.01 strcat(连接)
char* strcat(char* destination,const char* source)
<1>目标空间必须足够大且可变,保证可以存放源字符串;
<2>源字符串以‘\0’结束。
例:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
const char* str = "hello world";
char buff[32]="hi hi ";
strcat(buff, str);
printf("%s\n", buff);
system("pause");
return 0;
}
运行结果:
那么,字符串可以自己给自己追加吗?
这是不可以的。
假如‘abcd\0’自己拼接自己时会遇到‘\0’时停止,然而当a开始拷贝时已经覆盖‘\0’,当拼接到d时,准被拼接‘\0’时,‘\0’已经消失了,拼接不能终止。
3.02 strncat
char* strcat(char* destination,const char* source,size_t num)
例:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char str1[20];
char str2[20];
strcpy(str1, "To be ");
strcpy(str2, "or not to be");
strncat(str1, str2, 6);
printf("%s\n", str1);
system("pause");
return 0;
}
运行结果:
如果想拼接str2到str1中,需将strncat(str1, str2, 6);
改为
strncat(str1, str2, strlen(str2)+1);
4.01 strcmp(比较)
int strcmp(const char* str1,const char* str2)
<1>第一个字符串大于第二个字符串则返回大于0的数字;
<2>两字符串相等,则返回0;
<3>第一个字符串小于第二个字符串则返回小于0的数字;
例:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char str1[32] = "abcdefg";
char str2[32] = "abcdxyz";
int ret = strcmp(str1, str2);
printf("%d\n", ret);
system("pause");
return 0;
}
运行结果:
4.02 strncmp
int strncmp(const char* str1,const char* str2,size_t num)
例:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char str1[32] = "abcdefg";
char str2[32] = "abcdxyz";
int ret = strncmp(str1, str2,4);
printf("%d\n", ret);
system("pause");
return 0;
}
运行结果:
5.strstr() 函数
作用:搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。该函数是二进制安全的。
例1:
int main()
{
char str[] = "This is a simple string";
char* pch= strstr(str, "simple");
puts(pch);
system("pause");
return 0;
}
运行结果:
例2:
int main()
{
char str[] = "This is a simple string";
char* pch= strstr(str, "simple");
strncpy(pch, "sample", 6);
puts(str);
system("pause");
return 0;
}
运行结果:
例3:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char str[] = "This is a simple simple simple string";
char* pch = strstr(str, "simple");
while (pch) {
strncpy(pch, "sample", 6);
pch = strstr(str, "simple");
}
puts(str);
system("pause");
return 0;
}
运行结果:
6.strtok
char* strtok(char* str,const char* sep)
作用:
strtok()用来将字符串分割成一个个片段。参数s指向欲分割的 字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的 指针。
解释:
<1>sep参数是个字符串,定义了用作分隔符的字符集合;
<2>第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或多个分隔符分割的标记;
<3>strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指定这个标记的(注;strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改。)
<4>strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置;
<5>strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记;
<6>如果字符串中不存在更多的标记,则返回NULL指针。
例1:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char str[] = "abcd: fghi-xyz";
char *str1= stroke(str, ": _");
printf("%s\n", str1);
str1 = stroke(NULL, ": _");
printf("%s\n", str1);
str1 = stroke(NULL, ": _");
printf("%s\n", str1);
system("pause");
return 0;
}
例2:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
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, " ,.-");
}
system("pause");
return 0;
}
运行结果:
例3:
(理解)
#include<stdio.h>
#include<string.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
char* p = "zhaoqiansunli@du.name";
const char* sep = ".@";
char arr[30];
char* str = NULL;
strcpy(arr, p);//将数据拷贝一份,处理arr数组内容
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep));
{
printf("%s\n", str);
}
system("pause");
return 0;
}
运行结果:
7.strerror
char * strerror(int errnum)
作用:
通过标准错误的标号,获得错误的描述字符串 ,将单纯的错误标号转为字符串描述,方便用户查找错误。
例1:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
int main()
{
int i;
for (i = 0; i < 45; i++) {
printf("%d:%s\n", i, strerror(i)); //错误码 错误码描述
}
system("pause");
return 0;
}
运行结果:
例2:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
int main()
{
extern int errno;//errno是系统的全局变量,不需自己定义,只需声明便可使用
printf("%d:%s\n", errno, strerror(errno));
system("pause");
return 0;
}
运行结果:
例3:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
#pragma warning(disable:4996)
int main()
{
FILE* fp = fopen("log.txt", "r");
printf("%d:%s\n", errno, strerror(errno));/*错误码是2。程序调用函数或库函数失败时,会将错误码写入全局变量errno。可以通过strerror将错误码传入转成错误码描述*/
system("pause");
return 0;
}
运行结果:
8.
字符分类函数
字符转换函数
例1:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
#pragma warning(disable:4996)
int main()
{
int i=0;
char str[] = "This Is a Game...!";
while (str[i])
{
if (isupper(str[i]))
{
str[i] = tolower(str[i]);
}
i++;
}
printf("%s\n", str);
system("pause");
return 0;
}
运行结果:
例2:
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
#pragma warning(disable:4996)
int main()
{
int i=0;
char str[] = "This Is a Game...!";
char c;
while (str[i])
{
if (isalpha(str[i]))
{
if (isupper(str[i]))
{
c = tolower(str[i]);
//putchar(str);
}
else
{
c = str[i];
}
putchar(c);
}
i++;
}
system("pause");
return 0;
}
运行结果:
一…memcpy()
情况一:
#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
void* Mymemcpy(void* dest, const void* src, int count)
{
//char* p=(char*)dest;
while (count--)
{
void* ret = dest;
*(char*)dest = *(char*)src;
((char*)dest)++;
((char*)src)++;
}
return dest;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
//int arr2[] = { 0 };
Mymemcpy(arr + 2, arr, 12);
system("pause");
return 0;
}
调试结果:
我们想得到121236789,然而得到结果是121216789。这个实现过程不能处理内存重叠。
情况2:
#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
memcopy(arr + 2, arr, 12);
system("pause");
return 0;
}
运行结果为121236789,理论上为121216789
二…memmove()
#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
memmove(arr + 2, arr, 12);
system("pause");
return 0;
}
测试结果:
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#pragma warning(disable:4996)
int* Mymemmove(void* dest, const void* src, int count)
{
//char* p=(char*)dest;
void* ret = dest;
if (dest < src)
{
while (count--)
{
*(char*)dest = *(char*)src;
((char*)dest)++;
((char*)src)++;
}
}
else
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int arr2[] = { 0 };
Mymemove(arr + 2, arr, 12);
system("pause");
return 0;
}