成长之路---C语言笔记(构造类型之字符数组及字符串函数)

简介: 字符数组就是用于存放字符型数据的数组。在C语言中,字符串是作为字符数组来处理的,没有专门的字符串变量。字符串十分常用,因此C语言提供了许多专门处理字符串的函数。

决不要停止自学,也不要忘记,不管你已经学到了多少东西,已经知道了多少东西,知识和学问是没有止境的一鲁巴金

字符数组

字符数组就是用于存放字符型数据的数组。在C语言中,字符串是作为字符数组来处理的,没有专门的字符串变量。字符串十分常用,因此C语言提供了许多专门处理字符串的函数。

字符数组的定义

字符数组是用于存放字符变量的数组,每个数组元素存放一个字符。字符数组的定义和数值型数组类似:

char 数组名[常量表达式];

与数值型数组相同,需要使用下标来访问字符数组元素,下标值0开始。

字符数组在内存中的存储

由于字符型和整型通用,也可以使用整型数组来存放字符数据,但这样浪费空间。同样也可以定义二维字符数组。

b[0]

b[1]

....

b[5]

.....

b[9]

1

h

y

字符数组的初始化

1.对数组元素逐个赋初值,这个方法与数值型数组类似

char c[10]={'c','v','b'};

最后一个数组元素没有赋初值,自动赋值为空字符(即'\0',其ASCII的值为0,是一个非打印字符)

2.用字符串初始化,c语言规定,可以将字符串直接赋值给字符数组用于初始化。

char c[12]={"hello world"};

事实上在实际运用过程中常省略花括号,甚至省略数组长度

char c[]={"hello world"};

注:存储长度为字符串中字符个数+1,因为'\0'作为结束字符也占一个长度。

字符数组只有在初始化时才能将整个字符串一次性地赋值,一定义完,就只能逐个字符赋值。

字符串与字符串结束标志

C语言中,用双引号引起来的内容为字符串常量。没有专门用于存储字符串变量的类型,字符串被存储在以空字符('\n')结尾的char类型的数组中。空字符用来标记字符串结束的位置,因此'\ 0'也被称为字符串结束标志或者字符串结束符。0'是ASCII码表中的第0个字符,英文称为NUL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果。有了空字符作为字符串的结束符,就不必再以字符数组的长度来判断字符串的长度值得注意的是逐个字符地给数组赋值初始化并不会自动添加'\0',需要我们人为地添加。

字符数组的引用和输入与输出

  1. 字符数组的引用

字符数组的引用即字符数组元素的引用,如同字符型变量的使用,可以被赋值,参与表达式运算或进行输入输出。例如:

char c[5];
c[0]='c';
c[4]=c[2]+5;
for(i=0;i<5;i++)
c[i]='a'+i;
for(i=0;i<5;i++)
printf("c[%d]=%c",i,c[i]);

我们可以使用for语句逐个输出同时在C标准库中也为我们提供了一些函数为我们整体输入输出,在下面的文章中我会写到。

字符串的输入

scanf()函数

使用scanf()函数和转换符%s可以读取字符串,读取时以第一个非空白符作为字符串的开始,以下一个空白符作为字符串的结束。空白符包括空行,空格,制表符或换行符。

char a[6];
scanf("%s",a);

注:scanf()函数的输入项a是一个已定义的字符数组名,输入的字符串应该短于定义的长度,系统自动加'\0',如果输入内容过长,scanf()也会造成数据溢出。此时我们可以指定宽度来防止溢出如:%10s

特别注明:在VS编译器中因为安全性问题在实际使用中我们需要使用是scanf_s()代替,具体使用方法类似,同样我们也可以使用#define _CRT_SECURE_NO_WARNINGS来忽略该问题。

get()函数

在我们使用scanf()函数进行输入时每次只能输入一个字符并且当遇到空格时输入就停止了,为了让我们可以一次性输入一个句子gets()函数就诞生了,事实上C11标准委员会已经将其废除在VS2022中我们已经不能使用了,这里我们介绍2了一些它的替代品。

fgets()函数

char *__cdecl fgets(char *_Buffer, int _MaxCount, FILE *_Stream)

它含有三个参数,其中第2个参数指明了读入字符的最大数量(特别注明包括'\0'),第三个参数指明要读入的文件,如果读入从键盘输入的数据,则以stdin1stdin是C语言中标准输入流,一般用于获取键盘输入到缓冲区里的东西)作为参数,该标识符定义在stdio.h中。例如:

#include<stdio.h>
int main ()
{
    char a[SIZE];
    fgets(a,10,stdin);
    fputs(a,stdout);
    return 0;
 }

gets_s()函数

char *__cdecl gets_s(char *_Buffer, rsize_t _Size)

它包含两个参数,第二个参数为读入字符的最大数量。

注:gets_s()只从标准输入中读取数据,所以不需要第3个参数,如果gets_s()读到换行符,会直接将其丢弃而不是储存,如果gets_s()读到最大字符数都没有读到换行符,会执行以下几步。首先把目标数组中的首字符设置为空字符,读取并丢弃随后的输入直至读到换行符或文件结尾,然后返回空指针。接着,调用依赖实现的“处理函数”(或你选择的其他函数),可能会中止或退出程序。

字符串的输出

printf()函数

使用转换说明符%s即可输出字符串,输出时遇见结束符'\0'即停止输出。

#include<stdio.h>
int main()
{
    char a[] = "China";
    printf("%s", a);
    return 0;
}

puts()函数  

用于将一个字符串或一个字符数组中存放的字符串(以'\0'结束的字符序列)输出到终端,并在末尾自动添加一个换行符,puts()函数常与gets()函数配对使用。

#include<stdio.h>
int main()
{
    char a[20] = "Input a string ";
    puts(a);
    fgets(a, 10, stdin);
    puts("This string is");
    puts(a);
    return 0;
}

注:puts()函数在遇见空字符时会停止输出,因此要确保含有空字符

char a[]={"a","c"}
//这种情况是不会自动添加'\0'

字符串处理函数

C语言函数库提供了多个处理字符串的函数,最常用的函数包括strlen(),strcpy(),strncpy(),strcat(),strcmp(),strlwr()和strupr()。其函数原型在头文件string.h中

strlen()函数

strlen()函数用于统计字符串的长度,即字符串中包含的字符个数,但不包括字符串结束符'\0'。字符串可以是字符数组,也可以是字符串常量

unsigned int strlen(char*str);//函数原型
#include<stdio.h>
int main()
{
    char str[20];
    fgets(str,20,stdin);
    printf("Length of\"%s\"is%d.\n", str, strlen(str));
    printf("Length of\%s\is%d.","abcdefg",strlen("abcdefg"));
    return 0;
}

注:输出双引号时采用了转义字符的表达方式

strcpy()函数和strncpy()

字符数组与数值型数组一 样,不能进行整体赋值和复制,只能对数组元素逐个赋值或复制 如果希望整体复制可以使用strcpy()函数

strcpy(字符数组1,字符数组2);
char* strcpy (char* szCopyTo, const char* szSource);
//函数原型

注:strcpy()函数用于将字符串或字符数组赋值到字符数组1中,包括赋值串后的字符串结束符'\0'。

strcpy()函数不会检查目标空间是否有足够容纳源字符串,而strncpy()可以指定复制的最大字符数。

stmcpy(字符数组1,字符串2,最大长度)
char* stmepy (char* szCopyTo, const char* szSource, int n);
函数原型

注: 如果字符串2的字符数小于n,那么复制整个字符串(包括空字符);复制的最大长度不能超过n,如果字符串2的字符数大于等于n,那么只复制前n个字符,不会复制空字符。空字符不一定要复制,需要时可以手动添加一个即可。

#define _CRT_SECURE_NO_WARNINGS//添加原因见上方
#include<stdio.h>
#include<string.h>
int main()
{
    char str1[20], str2[20] = "hello world";
    strncpy(str1, str2, 5);
    str1[5] = '\0';
        puts(str1);
    return 0;
}

strcat()函数

strcat()函数用于将字符串2连接到字符数组1的字符串后面,并返回字符数组1的起始地址,字符串2保持不变,它可以是字符数组或字符串常量。

strcat(字符数组1,字符数组2);
char*strcat (char* szAddTo, const char* szAdd);
//函数原型
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
    char str1[20], str2[10];
    printf("strl:");
    fgets(str1,20,stdin);
    printf("str2:");
    fgets(str2, 20, stdin);
    strcat(str1, str2);
    printf("str1: %s", str1);
    return 0;
}

注:strcat()函数不会检查字符数组 1的空间是否足够,程序员应当保证字符数组1的长度足以连接字符串2,否则会发生越界错误。当连接时,将字符数组1中字符串结束符'0'去掉,将字符串2的各字符依次连接到字符数组1的末字符后,并在新字符串的末尾再加上字符串结束符'\0'。

strcmp()函数

strcmp()函数用于比较字符串,若两个字符串相同,则返回0;当字符串1大于字符串2时,则返回个正整数:当字符串1小于字符串2时, 则返回一个负整数。字符串的比较从各自第一个字符开始,并进行逐个一一对应比较(按字符的ASCII 码值大小进行)。若前面的对应字符相同,则继续往后比较,直到遇上第对不同的字符, 并以这对字符的大小作为字符串比较的结果。字符串1和字符串2可以是字符数组或字符串常量。

strcmp(字符串1,字符串2);
int strcmp (const char* sz1, const char* sz2);
//函数原型
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
    printf("%d ",strcmp("abc", "abd"));
    printf("%d ",strcmp("abcd", "abc"));
    printf("%d ", strcmp("abc", "abc"));
    return 0;
}

注:若"ab"<"abd",则strcmp("abc", "abd")返回负整数;若"abed"> "abe",则strcmp("abed","abe" )返回正整数;若"abe"自己与自己相等,则stremp("abc", "abe")返回 0。大多数情况下,stremp()函数用于比较两个字符串是否相等或按字母顺序排序,返回的值具体是多少 并不重要。

strlwr()函数和strupr()函数

strlwr()函数是用于将指定字符串中的大写字母转换成小写字母并返回。

strupr()函数是用于将指定字符串中的小写字母转换成大写字母并返回。

strlwr(字符串)
char* strlwr (char* szToConvert);
//函数原型
strupr(字符串)
char* strupr (char* szToConvert);
//函数原型
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
    char str[20];
    fgets(str,10,stdin);
    printf("%s\n", _strlwr(str));
    fgets(str,20,stdin);
    printf("%s\n", _strupr(str));
    return 0;
}

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