C语言·字符串

目录

变量、常量与字面量的区别

字符串字面量

解释

字符串字面量的延续

字符串字面量存储

字符串变量

C语言声明字符串

 初始化字符串变量

字符数组与字符指针

字符串的读和写​​​​​​​​​​​​​​


变量、常量与字面量的区别

字面量是指由字母,数字等构成的字符串或者数值,它只能作为右值出现(右值是指等号右边的值)。

常量和变量都属于变量,只不过常量是赋过值后不能再改变的变量,而普通的变量可以再进行赋值操作。

字符串常量在C语言里称为字符串字面量。本文主要介绍字符串变量和字符串字面量。

字符串字面量

解释

字符串字面量是用一对双引号括起来的字符序列:"when you came to a fork in the road,take it."

字符串字面量常常作为格式串出现在printf函数和scanf函数的调用中。

注意:

const char b = "when you came to a fork in the road,take it.";

这里面b是一个常量,"when you came to a fork in the road,take it."是字符串字面量。

通常情况下可以在任何C语言允许使用char *指针的地方使用字符串字面量。

char *p;
p = "abc";

char  ch;   ch = "abc"[1];  是对指针取下标,这里等于 ch = p[1];即ch 的值将会变成 b;

当然,当字符串字面量只包含一个字符时,字符串字面量和字符(串)常量就会变得不一样:字符串字面量"a"是用指针来表示的,字符(串)常量"a"是一个整数。

警告:不要在该使用字符串的时候使用字符,也不要在该使用字符的时候,使用字符串。

字符串字面量的延续

如果发现字符串字面量太长而无法防止在单独的一行以内,只要把第一行用字符\结尾,那么C语言就允许在下一行延续字符串字面量。除了(看不到的)末尾的换行符,在同一行不可以有其他字符跟在后面,当然使用"\"来延续有一个缺陷:字符串字面量必须从下一行的起始位置继续,不可以缩进:

printf(""when you came to a fork in the road,  take it. \
 -- Yogi Berra");

改进:当两条或者更多的字符串字面量相邻时(仅用空白字符分隔),编译器会把它们合并成一条字符串。这条规则允许把字符串分隔放在两行或者更多行中。

printf("when you came to a fork in the road,   take it."
        " -- Yogi Berra");

字符串字面量存储

字符串字面量是按照数组的方式来存储的。

对于长度为n的字符串字面量,c语言会给分配一个长度为n+1的内存空间(+1是给标志字符串末尾的额外字符(空字符)。字符:\0,而不是0。因为字符串字面量是按照数组的方式来存储的,编译器会把它看成是char *类型的指针。即调用时,指针指向首地址。

字符串变量

C语言声明字符串

只要保证字符串是以空字符结尾的,任何一维的字符数组都可以用来存储字符串。

[惯用法]  #define STR_LEN  80

                 …

                char str[STR_LEN +1] ;

这是程序员的惯用法,这样这个字符串最多存储80个字符。

 初始化字符串变量

字符串变量可以在声明时进行初始化:char  date1[8] = "June 14";

在这里,"June 14" 并不是字符串字面量,我们可以将上面的式子看成:

char  date1[8] = {'J', 'u', 'n', 'e', ' ', '1', '4', '\0' };

在C语言中没有纯粹的c语言字符串变量,可以通过一个字符数组等的形式来体现,这样就可以就可以将字符串字面量变成变量形式,对字符数组中的内容进行改变就是对字符串变量做出改变。

字符串变量初始化和数组的初始化特别相似,数组未初始化的会被自动初始化为0,那么存放字符串得数组会自动的初始化成\0,\0…

字符串变量可以在声明中可以省略它的长度:char  date1[] = "June 14";这种情况下,编译器会自动计算长度。

字符数组与字符指针

以下两个声明看起来很相似:

char  date[] = "June 14";                char *date = "June 14";

但是前者声明的date是一个数组,后者是一个指针。

在声明成一个数组时,存储在数组date中的字符是可以被修改的。此时date是一个数组名。在声明成一个指针时,指针指向字符串字面量,字符串字面量是不可以被修改的。此时date是一个变量,这个变量可以在程序执行期间指向其他字符串。 也就是说,当声明成指针时, "June 14"就不可以改变了,但指针可以不指向 "June 14";,去指向其他地址。

很严重的错误:

使用未初始化的指针变量作为字符串是非常严重的错误。

例:char  *p;

p[0] = 'a'; p[1] = 'b';  p[2] = 'c';p[3] = '\0';

因为这时未说明p指针指向哪里,p[0]没有指向a。

字符串的读和写

以字符串:char str[] = "Are we having fun yet ?";来举例说明

printf函数:

char str[] = "Are we having fun yet ?";
printf("%s\n",str);
//输出结果:Are we having fun yet ?
/*
    这里是逐个写字符串中的字符,遇到空字符停止。如果遇不到空字符,
    printf函数会越过字符串的末尾继续写,直到最终在内存的某个地方找到空字符为止。
*/

char str[] = "Are we having fun yet ?";
printf("%.6s\n",str);
//输出结果:Are we
/*
    如果只想显示字符串的一部分,可以使用转换说明%.ps,p是要显示的字符数量。
*/

puts函数:puts(str);

puts函数只有一个参数,即需要显示的字符串str。在写完字符串后,puts函数总会自动添加一个额外的换行符,从而前进到下一个输出行的开始处。


scanf函数:

%s允许scanf函数把字符串读入字符数组:scanf("%s",str);

但是这里不需要&符号,因为str是一个数组名,编译器在把它传递给函数时会把它当作指针来处理。调用时,scanf函数在开始读取时会跳过空白字符,然后读入字符并存储到str中,直到再次遇到空白字符为止,因此scanf函数读入字符串永远不会包含空白字符。换行符、制表符等都能使scanf函数停止读入。

scanf函数始终会在字符串的末尾存储一个空字符。

scanf函数通常不会读入一整行输入。

char sentence [SENT_ENCE + 1];

printf("Enter a sentence : \n");
scanf("%s",sentence);
//假设输入的是 To C, Or not to C: that is the question.

那么scanf函数只会存储To到sentence里。


gets函数:

为了使一次读入一整行的输入,可以使用gets函数。

gets函数不会在开始读取时会跳过空白字符。

gets函数会持续输入,直到找到换行符为止,会自动忽略换行符,不会把它存储到数组中,用空字符代替换行符。

char sentence [SENT_ENCE + 1];

printf("Enter a sentence : \n");
gets(sentence);
//假设输入的是 To C, Or not to C: that is the question.

gets函数会将输入全部存入sentence。


逐个字符读取字符串:

很多时候,我们想兼顾上面两个读取函数的优点:

假设我们所需要的函数不会跳过空白字符,在第一个换行符(不存储到字符串中)处停止读取,并且忽略额外的字符,那么我们可以: int read_line (char str[],int n);       str 表示用来存储输入的数组,n是读入字符的最大数量。

这种情况下,read_line函数主要由一个循环构成、只要str中还有空间(读取的个数没有超过n),此循环就会调用getchar函数逐个读入字符并把它们存储到str中。在读入换行符时循环终止。

scanf函数和gets函数等标准函数会自动在输入字符串的末尾放置一个空字符;其他情况下,我们需要手动添加空字符。

int read_line(char str[], int n)
{
    int ch, i = 0;
//ch的类型是int型,而不是char型,这是因为getchar函数会把它读取的字符作为int类型的值返回。
    while((ch = getchar()) != '\n')
    {
        if(i < n)
        {
            str[i++] = ch;
        }
    }
    str[i] = '\0';
    return i;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wmpreturn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值