C语言之字符串详解和内存操作函数的使用

1.初始字符串

  • 在C语言中,一串以“”(双引号)引起的以’ \n '(NULL)结尾的字符就是字符串。

  • char* s1 = “Hello”;(s1中的字符实际为’H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\n’)
    char* s2 = “Sheena”;(s2中的字符实际为’S’ ‘h’ ‘e’ ‘e’ ‘n’ ‘a’ ‘\n’)
    char* s3 = “string”;(s3中的字符实际为’s’ ‘t’ ‘r’ ‘i’ ‘n’ ‘g’ ‘\n’)
  • 字符串是一个常量,不可以更改。
  • ""表示一个空字符串。

2.字符数组

  • C语言之简单理解数组中我们有学习到字符数组--------就是数组中存的是字符。

  • 故上述的s1、s2、s3用字符数组定义如下:
    char s1[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\n’};
    char s2[] = {‘S’, ‘h’, ‘e’, ‘e’, ‘n’, ‘a’, ‘\n’};
    char s3[] = {‘s’, ‘t’, ‘r’, ‘i’, ‘n’, ‘g’, ‘\n’};
    char s4 = “hello sheena!”;//也可以这样进行初始化

  • 字符数组是一个数组,其中的值可以更改。

3.字符串函数

(1)strlen

  • size_t strlen( const char* str);
  • 该函数是用来求字符串的长度的函数。
  • 字符串是以’ \0 ‘作为结束标志,故字符串长度是指不包含’ \0 '的字符的个数。
  • 注意该函数返回值为size_t无符号类型的。
#include <stdio.h>
#include <string.h>

int main()
{
	char* s = "hello sheena!";
	size_t len = 0;
	len = strlen( s );
	printf("%d\n", len);//13
	
	return 0;
}

在这里插入图片描述
(2)strcpy和strncpy
①strcpy

  • 该函数为将一个字符串所有的值拷贝到另一个字符串中。
  • char* strcpy( char* destination, const char* source );
  • 源字符串必须以‘ \0 ’结束。
  • 该函数拷贝的时候会将源字符串的’ \0 '也拷贝到目标字符串中。
#include <stdio.h>
#include <string.h>

int main()
{
	char* d= "hello sheena!";
	char* s = "hehehe";
	char str1[30];
	char str2[30];
	strcpy(str1, d);
	strcpy(str2, s);

	printf("%s\n", str1);
	printf("%s\n", str2);

	return 0;
}

在这里插入图片描述
②strncpy

  • 该函数是拷贝源字符串的num个字符到目标字符串中。
  • char* strncpy( char* destination, const char* source, size_t num);
  • 若源字符串的长度小于num,则拷贝完源字符串后,在目标字符串的后边追加0,直到长度为n为止。
  • 拷贝时不会在后面自动添加’ \0 '。
#include <stdio.h>
#include <string.h>

int main()
{
	char dst[10];
	char *src = "hello sheena!";

	strncpy(dst, src, 5);
	//dst[5] = '\0';

	printf("%s\n", dst);

	return 0;
}

在这里插入图片描述

  • 由上述代码与结果我们不难发现,若我们不手动在最终的目标字符串中加’ \0 ‘,它将会输出乱码,因为输出的时候是读到’ \0 ‘为止,而strncpy不会在字符串后面自动添加’ \0 '。
  • 故我们需要在拷贝之后,若拷贝的源字符串的长度中不含’ \0 ',就需要我们手动添加,正确写法如下所示
#include <stdio.h>
#include <string.h>

int main()
{
	char dst[10];
	char *src = "hello sheena!";

	strncpy(dst, src, 5);
	dst[5] = '\0';

	printf("%s\n", dst);

	return 0;
}

在这里插入图片描述
(3)strcmp和strncmp
①strcmp

  • 该函数是比较两个字符串的大小(按ASCII码值比较)
  • int strcmp( consr char* str1, const char* str2);
  • 返回值规则为:若第一个字符串大于第二个字符串,则返回大于0的数字。若第一个字符串等于第二个字符串,则返回0。若第一个字符串小于第二个字符串,则返回小于0的数字。
  • 先比较两个字符串的第一个字符的ASCII码值,若相等则再比较两个字符串的第二个字符的ASCII码值,依次类推。
#include <stdio.h>
#include <string.h>

int main()
{
	char* d= "hahehe";
	char* s = "hehehe";
	int res = 0;

	res = strcmp(d, s);
	
	if (res > 0)
		printf("res的值为: %d, 字符串d大于字符串s\n", res);
	else if(res == 0)
		printf("res的值为: %d, 字符串d等于字符串s\n", res);
	else 
		printf("res的值为: %d, 字符串d小于字符串s\n", res);


	return 0;
}

在这里插入图片描述

②strncmp

  • 该函数为比较字符串1与字符串2的指定长度的大小。(比较ASCII码值)
  • int strncmp( const char* str1, const char* str2, size_t num);
  • 返回值规则为:若第一个字符串大于第二个字符串,则返回大于0的数字。若第一个字符串等于第二个字符串,则返回0。若第一个字符串小于第二个字符串,则返回小于0的数字。
  • 先比较两个字符串的第一个字符的ASCII码值,若相等则再比较两个字符串的第二个字符的ASCII码值,依次类推。
#include <stdio.h>
#include <string.h>

int main()
{
	char* d= "hexehe";
	char* s = "hehehe";
	int res = 0;

	res = strncmp(d, s, 3);
	
	if (res > 0)
		printf("res的值为: %d, 字符串d大于字符串s\n", res);
	else if(res == 0)
		printf("res的值为: %d, 字符串d等于字符串s\n", res);
	else 
		printf("res的值为: %d, 字符串d小于字符串s\n", res);


	return 0;
}

在这里插入图片描述
(4)strcat和strncat
① strcat

  • 该函数是将源字符串拼接到目标字符串中。
  • char* strcat ( char* destination, const char* source);
  • 源字符串必须以’ \0 '结束
  • 目标字符串的空间必须足够大,能容纳下源字符串的内容。
#include <stdio.h>
#include <string.h>

int main()
{
	char d[100]= "hello ";
	char* s = "sheena";

	strcat(d, s);
	printf("%s\n", d);

	return 0;
}

在这里插入图片描述
②strncat

  • 该函数是指将源字符串的长度为num的字符拼接到目标字符串。
  • char* strncat ( char* destination, const char* source, size_t num);
  • 拼接之后,该函数会自动将’ \0 '挪到最后。
#include <stdio.h>
#include <string.h>

int main()
{
	char d[100]= "hello ";
	char* s = "sheenahellojhhjdh";

	strncat(d, s, 6);
	printf("%s\n", d);

	return 0;
}

在这里插入图片描述
(5)strstr

  • 该函数是判断一个字符串是否为另一个字符串的子串。
  • char* strstr ( const char* str1, const char* str2);
  • 返回字符串str2第一次出现在字符串str2中的位置,若没有则返回NULL。
#include <stdio.h>
#include <string.h>

int main()
{
	char* d1 = "hello";
	char* s = "sheenahellojhhjdh";
	char* d2 = "abcd";

	char *res1;
	res1 = strstr(s, d1);

	char *res2;
	res2 = strstr(s, d2);

	printf("res1 = %s, res2 = %s\n", res1, res2);

	return 0;
}

在这里插入图片描述
(6)strtok

  • 该函数是根据一个分隔符将一个字符串分隔成几个部分,然后打印出来。
  • char* strstr ( char* str, const char* sep);
  • sep参数是个字符串,定义了用作分隔符的字符集合。
  • 第一个参数是指一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用’ \0 '结尾,返回一个指向这个标记的指针。
  • strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。
  • strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,保存它在字符串中的位置。
  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回NULL指针。
#include <stdio.h>
#include <string.h>

int main()
{
	char str[] = "-this is a sample-hello sheena-hello world!";
	char* res;
	res = strtok(str, "-");

	while (res)
	{
		printf("%s\n", res);
		res = strtok(NULL, "-");
	}

	return 0;
}

在这里插入图片描述
(7)strerror

  • 该函数是返回错误码对应的错误信息。
  • char* strerror( int errnum );
  • 必须包含头文件error.h
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
	FILE * pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("错误信息为: %s\n", strerror(errno));

	return 0;
}

在这里插入图片描述

(8)tolower 和 toupper
①tolower

  • 该函数字符转换的。将一个大写字符转换为小写字符。
  • int tolower( int c );
  • 头文件为ctype.h
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
	char* str = "Hello Sheena, Hello World";
	int i = 0;
	char c;
	while (str[i])
	{
		c = str[i];
		if (c >= 'A' && c <= 'Z')
			c = tolower(c);
		putchar(c);
		++i;
	}

	return 0;
}

在这里插入图片描述
②toupper

  • 该函数字符转换的。将一个小写字符转换为大写字符。
  • int toupper( int c );
  • 头文件为ctype.h
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
	char* str = "Hello Sheena, Hello World";
	int i = 0;
	char c;
	while (str[i])
	{
		c = str[i];
		if (c >= 'a' && c <= 'z')
			c = toupper(c);
		putchar(c);
		++i;
	}

	return 0;
}

在这里插入图片描述

4.内存操作函数

(1)memcpy

  • 该函数从source的位置开始向后拷贝num个字节的数据到destination的内存位置。
  • void* memcpy( void* destination, const void* source, size_t num);
  • 这个函数在遇到’ \0 '的时候并不会停下来。
  • 若source和destination有任何的重叠,拷贝的结果都是未定义的。
#include <stdio.h>
#include <string.h>

int main()
{
	int a1[10];
	int a2[] = { 1, 2, 3, 4, 5 };
	double a3[2];
	double a4[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
	
	memcpy(a1, a2, sizeof(a2) * sizeof(int));
	memcpy(a3, a4, 16);
	
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", a1[i]);
	}
	printf("\n");
	
	for (int i = 0; i < sizeof(a3) / sizeof(double); ++i)
	{
		printf("%f ", a3[i]);
	}
	printf("\n");


	return 0;
}

在这里插入图片描述
(2)memmove

  • 该函数是memcpy作用差不多。
  • void* memmove( void* destination, const void* source, size_t num);
  • 和memcpy的差别就是memmove函数处理的source和destination是可以重叠的。
  • 若source和destination出现重叠,就必须使用memmove函数处理。
#include <stdio.h>
#include <string.h>

int main()
{
	int arr[10] = { 1, 2, 3, 4, 5 };
	
	memcpy(arr , arr + 2, 12);
	
	for (int i = 0; i < 5; ++i)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");


	return 0;
}

在这里插入图片描述
(3)memcmp

  • 比较ptr1和ptr2指针开始的num个字节的大小。
  • int memcmp ( const void* ptr1, const void* ptr2, size_t num );
  • 返回值和strcpy一样。
#include <stdio.h>
#include <string.h>

int main()
{
	int arr1[] = { 1, 2, 3, 4, 5 };
	int arr2[] = { 1, 2, 3, 5, 55 };
	int res1 = 0, res2 = 0;

	res1 = memcmp(arr1, arr2, 12);
	if (res1 > 0)
		printf("res1的值为:%d, arr1 > arr2\n", res1);
	else if(res1 == 0)
		printf("res1的值为:%d, arr1 = arr2\n", res1);
	else
		printf("res1的值为:%d, arr1 < arr2\n", res1);

	res2 = memcmp(arr1, arr2, 20);
	if (res2 > 0)
		printf("res2的值为:%d, arr1 > arr2\n", res2);
	else if (res2 == 0)
		printf("res2的值为:%d, arr1 = arr2\n", res2);
	else
		printf("res2的值为:%d, arr1 < arr2\n", res2);

	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值