C语言字符串

字符串

我们在前面的章节中介绍过,数组是同类数据类型元素的集合。数据类型可能是int,char,float,double类型等等。

字符元素的集合,我们称之为字符数组。如果一组字符不是用中括号[]而是使用双引号""括起来的,称为字符串。字符串的最后一个字符永远是'\0',而字符数组不是。这就是字符串和字符数组的主要区别。

以下是字符串不同于字符数组的特点:

  1. 字符串的数据类型始终为char;
  2. 默认情况下,字符串的最后一个元素始终为空字符('\ 0');
  3. 字符串常量用双引号"<string_Constant>" 编写;
  4. 字符串输入或输出需要使用%s格式符。

语法

char string_name[stringSizeMax+1];

注意:+1是因为字符串最后一个默认字符默认为'\ 0'。

例如:
char name[20];
其中name为字符串名称,[20]表示输入的字符数必须小于20。

字符串初始化

字符串初始化是在声明时为字符串赋值的过程。如果我们使用某个常量初始化字符串,则不需要给出字符串的size大小。

字符串变量初始化

char string_name[]="string-literal";
char str[]="hello";

在上面的字符串初始化中,"hello"是字符串常量,存储在只读内存中。在赋值给'str'数组时,计算机将"hello"保存到堆栈中。因此,所有操作都将在堆栈副本上执行,并且可以更改字符串。

str[0]='M'//正确,因为程序操作的是字符串常量的副本.

字符串指针初始化

char *string_pointer="string-literal";
char *str="hello";

在上面的字符串初始化中,"hello"是字符串常量,存储在只读内存中。而str是指向该字符串的指针,这意味着str拥有一个字符串常量的地址,这是只读的地址,因此任何写操作都是不允许的。

str[0]='M'//错误,因为str指针指向的是字符串常量的地址.

这就是为什么要避免混淆,总是在这样的字符串指针声明中使用const,如下所示:

const char *str="hello";//建议使用这种字符串指针声明

字符串用数组如何表示

字符串表示形式:char name[] ="Amit";
数组表示形式:char name[] = {'A','m','i','t','\0'};

通过上面对比,你可以看到在数组中我们必须手动插入'\0'字符,而字符串的最后一个元素默认就是'\0'。

在C中使用%s格式符

因为字符串是字符元素的数组,所以我们可以使用%c读取或写入字符元素,但是我们必须使用循环遍历整个数组,因为%c一次只能读取或写入一个字符。

%s格式符可以让我们不需要使用循环的方法输出,它利用了字符串中存在'\0'字符或者空格符的优势,可以一次性读取或写入完整的字符串。

当我们使用%s时,它将开始从文件读取或写入文件,直到遇到'\0'字符或空格符为止。

程序:

#include <stdio.h>
 
 
int main() 
{
    
   char name[100];
    
    printf("Enter any String without Space : ");
    
    scanf("%s",name); /*name=string name= base address of string*/
    
    printf("\nEnterd String is : %s",name);
    
    printf("\nEnter any String with Space : ");
    
    scanf("%s",name); /*name=string name= base address of string*/
    
    printf("\nEnterd String is : %s",name);
    
    return 0;
}

输出结果:

Enter Any String Without Space : HelloChina
Entered string is : HelloChina
Enter Any String with Space : Hello China
Entered string is : Hello

gets()函数

上面的例程中,我们可以看到,如果从键盘上输入的字符串中间存在空格符,scanf函数会将空格符当做字符串的截止符。所以当输入"Hello China"时,输出只能显示"Hello"。

为了解决这个输入的问题,我们可以使用gets()函数,而不是使用带有%s说明符的scanf作为字符串输入,gets()函数是库定义的函数(stdio.h)。

语法:

char* gets(char *string_ptr);

string_ptr:指向字符串或者字符串变量的指针;
gets()函数不需要%s说明符,因为它只接受字符串。
该函数从stdin文件中获取输入并复制到string_ptr指向的缓冲区中直到遇到空字符('\0')为止。它将不会像scanf()函数那样遇到空格符就终止。

返回值:
成功:返回指向输入字符串的指针
失败:空指针(NULL)

例程:

#include <stdio.h>
 
int main() 
{
    
    char name[100];
    
    printf("Enter any String with or without Space: ");
    
    gets(name); /*name=string name= base address of string*/
    
    printf("\nEnterd String is : %s",name);
    
    return 0;
}

输出结果:

Enter any String with or without Space : hello how are you
Enterd String is : hello how are you

puts()函数

printf函数没有像scanf函数那样,遇到空格符就终止字符串。但printf输出字符串时,需要使用%s的格式符。然而puts函数完全不需要告诉编译器输出数据的类型格式。

语法:

int puts(char *string_ptr);

string_ptr:指向字符串或者字符串变量的指针;
puts函数不需要%s说明符,因为它只接受字符串。
puts()函数从string_ptr指向的buffer中获取数据,并将其复制到stdout文件以在控制台上显示输出。

返回值:
成功:传输到标准输出文件的字节数。
失败:0

例程:

#include <stdio.h>
 
int main() 
{
    
    char name[100];
    
    printf("Enter any String with or without Space: ");
    
    gets(name); /*name=string name= base address of string*/
    
    //printf("\nEnterd String is : %s",name);
 
    puts(name);
    
    return 0;
}

输出结果:

Enter any String with or without Space : hello how are you
Enterd String is : hello how are you

下一节