C语言:字符串和字符串函数

字符串和字符串函数

函数:gets()、gets_s()、fgets()、puts()、fputs()、strcat()、strncat()、 strcmp()、strncmp()、strcpy()、strncpy()、sprintf()、strchr()
创建并使用字符串
使用C库中的字符和字符串函数,并创建自定义的字符串函数
使用命令行参数

表示字符串和字符串IO

字符串是以空字符(\0)结尾的char类型数组

和printf()函数一样,puts()函数也属于stdio.h系列的输入/输出函数。但 是,与printf()不同的是,puts()函数只显示字符串,而且自动在显示的字符串末尾加上换行符.

在程序中定义字符串

  1. 字符串字面量(字符串常量)

从ANSI C标准起,如果字符串字面量之间没有间隔,或者用空白字符 分隔,C会将其视为串联起来的字符串字面量。例如:

char greeting[50] = "Hello, and"" how are" " you"
" today!";

//与下面的代码等价:
char greeting[50] = "Hello, and how are you today!";

字符串常量属于静态存储类别(static storage class),这说明如果在函 数中使用字符串常量,该字符串只会被储存一次,在整个程序的生命期内存 在,即使函数被调用多次。用双引号括起来的内容被视为指向该字符串储存 位置的指针。这类似于把数组名作为指向该数组位置的指针。

  1. 字符串数组和初始化

定义字符串数组时,必须让编译器知道需要多少空间。一种方法是用足 够空间的数组储存字符串。

const char m1[40] = "Limit yourself to one line's worth.";

在指定数组大小时,要确保数组的元素个数至少比字符串长度多1(为 了容纳空字符)。所有未被使用的元素都被自动初始化为0(这里的0指的是 char形式的空字符,不是数字字符0)

还可以使用指针表示法创建字符串。例如,程序清单11.1中使用了下面 的声明:

const char * pt1 = "Something is pointing at me.";
//该声明和下面的声明几乎相同:
const char ar1[] = "Something is pointing at me.";
  1. 数组和指针

初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针 只把字符串的地址拷贝给指针
在数组形式中,ar1是地址常量。不能更改ar1,如果 改变了ar1,则意味着改变了数组的存储位置(即地址)。可以进行类似 ar1+1这样的操作,标识数组的下一个元素。但是不允许进行++ar1这样的操 作。
指针形式(*pt1)也使得编译器为字符串在静态存储区预留29个元素的 空间。另外,一旦开始执行程序,它会为指针变量pt1留出一个储存位置, 并把字符串的地址储存在指针变量中。该变量最初指向该字符串的首字符, 但是它的值可以改变。因此,可以使用递增运算符。例如,++pt1将指向第 2 个字符

  1. 数组和指针的区别

假设有下面两个声明:

char heart[] = "I love Tillie!"
const char *head = "I love Tillie!"

两者主要的区别是:数组名heart是常量,而指针名head是变量。

两者都可以使用数组表示法

两者都能进行指针加法操作

只有指针表示法可以进行递增操作

建议在把指针初始化为字符串字面 量时使用const限定符


  1. 字符串数组
const char *mytalents[LIM] = {
"Adding numbers swiftly",
"Multiplying accurately", "Stashing data",
"Following instructions to the letter",
"Understanding the C language"
};

char yourtalents[LIM][SLEN] = {
"Walking in a straight line",
"Sleeping", "Watching television",
"Mailing letters", "Reading email"
};

从某些方面来看,mytalents和yourtalents非常相似。两者都代表5个字符 串。使用一个下标时都分别表示一个字符串,如mytalents[0]和 yourtalents[0];使用两个下标时都分别表示一个字符,例如 mytalents[1][2]表 示 mytalents 数组中第 2 个指针所指向的字符串的第 3 个字符’l’, yourtalents[1][2]表示youttalentes数组的第2个字符串的第3个字符’e’。而且, 两者的初始化方式也相同。

mytalents数组是一个内含5个指针的数组,在我们的系统中共占用40字节.而yourtalents是一个内含5个数组的数组,每个数 组内含40个char类型的值,共占用200字节。所以,虽然mytalents[0]和 yourtalents[0]都分别表示一个字符串,但mytalents和yourtalents的类型并不相 同。mytalents中的指针指向初始化时所用的字符串字面量的位置,这些字符 串字面量被储存在静态内存中;而 yourtalents 中的数组则储存着字符串字面 量的副本,所以每个字符串都被储存了两次。此外,为字符串数组分配内存 的使用率较低。yourtalents 中的每个元素的大小必须相同,而且必须是能储 存最长字符串的大小。

综上所述,如果要用数组表示一系列待显示的字符串,请使用指针数 组,因为它比二维字符数组的效率高。但是,指针数组也有自身的缺点。
mytalents 中的指针指向的字符串字面量不能更改;而yourtalentsde 中的内容 可以更改。所以,如果要改变字符串或为字符串输入预留空间,不要使用指 向字符串字面量的指针


字符串输入

分配空间

如果想把一个字符串读入程序,首先必须预留储存该字符串的空间,然 后用输入函数获取该字符串
要做的第 1 件事是分配空间,以储存稍后读入的字符串。

gets函数

在读取字符串时,scanf()和转换说明%s只能读取一个单词。可是在程序 中经常要读取一整行输入,而不仅仅是一个单词。许多年前,gets()函数就 用于处理这种情况。gets()函数简单易用,它读取整行输入,直至遇到换行 符,然后丢弃换行符,储存其余字符,并在这些字符的末尾添加一

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值