C语言(四)字符串与字符数组

举报
槿泽 发表于 2022/11/30 19:36:23 2022/11/30
【摘要】 字符串与字符数组 字符和字符串字符普通字符:‘a’,‘1’转义字符:’\a’,’\n’…字符串“Boy”,”Maye”字符与字符串的区别​ 1,形式上不同 c风格字符串 以\0结尾的字符串​ 2,本质上:字符串有结束符 ‘\0’字符A和字符串A所占内存空间不一样,以下代码输出分别是多少呢?printf("%d %d", sizeof('a'),sizeof("a")); 字符串与字符...

字符串与字符数组

字符和字符串

字符

  • 普通字符:‘a’,‘1’
  • 转义字符:’\a’,’\n’…

字符串

  • “Boy”,”Maye”

字符与字符串的区别

​ 1,形式上不同 c风格字符串 以\0结尾的字符串
​ 2,本质上:字符串有结束符 ‘\0’

字符A和字符串A所占内存空间不一样,以下代码输出分别是多少呢?

printf("%d %d", sizeof('a'),sizeof("a"));

字符串与字符数组

特点:

  • 字符数组可以没有’\0’
  • 字符串必须要有’\0’
  • 字符数组可以存储字符串

字符串一定是字符数组,字符数组不一定是字符串

下列字符数组存储的是不是字符串:

  • char str[10] = {‘1’,‘b’,‘c’}; //是字符串,没有存满自动加了\0
  • char str[1] ={’\0’}; //是字符串 等价于””
  • “abcdedf”; //也是字符串,编译器会自动的在双引号最后加,上\0
  • char str[10] =“abcdef"; //字符串可以用字符数组表示{‘a’,‘b’…’\0’}
  • char str[10]={’‘a,”,”b”,”c”,’\0’} //不是字符串
  • char *p=”maye”; //一个字符指针指向字符串

总结:

  • 编译器不会给字符数组自动添加’\0’

  • 编译器会自动给双引号的字符串字面值加上’\0’

  • 指针指向的字符串是常量,是没法修改的。

字符数组的输入

getchar

char str[10];
for(int i=0;i<10;i++)
{
    str[i] = getchar();
}
puts(str);	//如果结尾没有'\0',输出结果将不可预料,可以改为逐个字符输出

  • 在结尾自动加上’\0‘
for(int i=0;i<10;i++)
{
    str[i] = getchar();
    if(str[i] == '\n')
    {
        str[i] = '\0';
        break;
    }
}

scanf

  • 使用scanf输入字符串时,遇到空格会自动截断,遇到回车结束,自动添加’\0’
  • 输入超出范围时,不会进行越界检查,甚至能完全输出

gets_s

  • 能读取空格,遇到回车结束,自动添加’\0’
  • 输入超出范围时,会进行越界检查,如下图

为啥printf、puts能输出字符串?

由于C语言中没有真正的字符串类型,可以通过字符数组表示字符串,因为它的元素地址是连续的,这就足够了。
(1)从首地址开始逐字节寻址,把存储单元(一个字节)内的数据转换为ASCII字符格式输出。

(2)直到某一个字节内存的元素为字符’\0’时,输出此字符并且寻址结束。

如果字符数组里没有’\0’,那么使用printf (%s) 输出时,就找不到正确的结束标志,就会多输出一些乱码。

字符串处理函数

strlen

int strlen ( const char *str )

  • 求字符串长度(不包括\0),注意和sizeof的区别
strlen("hello maye");	

strcpy/strncpy

char *strcpy( char *dest, const char *src )

  • 把一个src拷贝到dest中去,要保证dst缓冲区有足够的内存
  • strcpy 会在dest结尾添加\0
  • strncpy 不会在dest结尾添加\0
char dest[10];
strcpy(dest, "maye");
puts(dest);

strcmp/strncmp

int strcmp( char *str1, char *str2 )

  • 比较str1和str2,str1>str2 返回1,str1==str2 返回0,否则返回-1
int res = strcmp("maye", "maye");
printf("res:%d\n", res);

strcat/strncat

char *strcat(char *dest, const char *src)

  • 把src连接到dest的末尾(\0的位置)
char dest[20]="hello ";
strcat(dest, "maye");
puts(dest);

strchr/strrchr

char* strchr(char* _String, int _Ch)

  • 在字符串string中查找字符val,存在返回val的开始位置,否则返回NULL
char words[] = "hello every one,My name's maye";
puts(strchr(words, 'o'));

strstr

char* strstr(char* _String, char * _SubString)

  • 在字符串string中查找子串substr,存在返回substr的开始位置,否则返回NULL
char words[] = "hello every one,My name's maye";
puts(strstr(words, "one"));

memcmp

int memcmp( void const* _Buf1, void const* _Buf2,size_t _Size);

  • 内存比较,不仅可以比较字符串,还可以比较其他的内存
int arr[5] = { 1,2,6,4,5};
int arr1[5] = { 1,2,5,4,5 };
int ok = memcmp(arr, arr1, sizeof(int) * 5);
int ok1 = strcmp(arr, arr1);
printf("%d  %d\n", ok,ok1);

memcpy

void* memcpy( void* _Dst, void const* _Src, size_t _Size);

  • 内存拷贝
int temp[5];
memcpy(temp, arr,sizeof(int)*5);
//strcpy(temp, arr);		//复制整型数组会有问题,不知道什么时候结束

for (int i = 0; i < 5; i++)
{
	printf("%d ", temp[i]);
}

memset

void* memset( void* _Dst, int _Val,size_t _Size);

  • 按字节对内存进行初始化
char num[5];
memset(num, 127, sizeof(char) * 5);
for(int i = 0; i < 5; i++)
{
	printf("%d ", num[i]);
}

sprintf

int sprintf(char *buffer, char *format [,argument,…]);

sprintf和printf类似,但不是打印到控制台,而是将内容作为 C字符串存储在buffer指向的缓冲区中。 缓冲区的大小应该足够大以包含整个结果字符串。 终止空字符\0会自动附加在内容之后。

int main()
{
	char str[50] = { 0 };
	sprintf(str, "%s is %d years old!", "顽石", 18);
	printf("%s", str);

	return 0;
}

sscanf

int sscanf(char *buffer, char *format [,argument,…]);

从buffer读取数据,并根据参数格式将他们存储到由附加参数给出的位置,就像使用了scanf一样。

int main()
{
	char str[] = "maye is 18 years old";

	char name[10] = { 0 };
	int age = 0;
	//从字符串中获取姓名和年龄
	sscanf(str, "%s %*s %d", name, &age);
	printf("%s %d\n", name, age);

	return 0;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。