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

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

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

字符串与字符数组

字符和字符串

字符

  • 普通字符:‘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;
}


目录
相关文章
|
1月前
|
存储 算法 C语言
【C语言】字符常量详解
字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。
148 11
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
62 10
|
1月前
|
存储 C语言 开发者
【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)
在C语言中,格式化输出通过 `printf` 函数等格式化输出函数来实现。格式说明符(占位符)定义了数据的输出方式,标准ISO/IEC 9899:2024(C23)对这些格式说明符进行了详细规定。本文将详细讲解格式说明符的组成部分,包括标志字符、宽度、精度、长度修饰符和类型字符,并适当增加表格说明。
44 6
|
1月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
94 6
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
69 5
|
2月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
108 4
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
2月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
60 4