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;
}


目录
相关文章
|
6天前
|
存储 C语言 C++
【C语言数组】
【C语言数组】
|
6天前
|
算法 C语言
C语言------数组
这篇文章是关于C语言数组的实训,包括一维数组、二维数组和字符数组的定义、赋值、输入、输出方法,并通过实例代码演示了数组的使用和一些基本算法,如冒泡排序。
C语言------数组
|
18天前
|
存储 编译器 程序员
七:《初学C语言》— 数组
【8月更文挑战第2天】本篇文章详细讲解了一维数组和二维数组的创建、使用和初始化及如何使用sizeof()计算数组中的元素个数。并附带了多个教学源码及代码练习
34 1
七:《初学C语言》— 数组
|
23小时前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
11 4
|
7天前
|
编译器 C语言
【C语言小知识】ctype.h系列的字符函数
【C语言小知识】ctype.h系列的字符函数
|
7天前
|
存储 编译器 C语言
C语言——数组
C语言——数组
|
12天前
|
存储 C语言
C语言(数组)
C语言(数组)
23 6
|
1天前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
1天前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
1天前
|
存储 编译器 程序员
【C语言篇】从零带你全面了解数组(超详细)
有时候,数组在创建的时候,我们需要给定⼀些初始值,这种就称为初始化。