字符串及其操作函数

字符数组和字符串

&字符数组和字符串的概念
&字符数组的初始化

&字符串的输入输出
&综合举例

字符数组和字符串的概念
字符数组是元素类型为字符的数组 ,它既具有普通数组的一般性质 ,又具有某些特殊性质。
字符串常量是用双引号包围的字符序列。存储字符串常量时,系统会在字符序列后自动加上 ‘/0’,标志字符串的结束。字符串的长度定义为字符串中的有效字符数,不包括结束标志 ‘/0’和双引号。
字符串变量是以 ‘/0’作为结束标志的字符数组。字符串变量用于存储和处理字符串常量。在书中统称为字符串的,既可能是字符串常量也可能是存储了字符串常量的字符串变量,即特殊的字符数组。
字符数组有两种用法 :一是当作字符的数组来使用。这时的用法与整数的数组、 实数的数组等相同,对字符数组的输入、输出、赋值、引用等都是针对单个的元素进行。二是更为重要的用法即存储、处理字符串。这时它除了可以像普通数组一样使用外,还可以把字符串作为一个整体进行操作。

字符数组的初始化
(1)用字符对字符数组初始化 这时把字符数组当作普通数组看待 , 产生的数组不会有结束符 ‘/0’。当数据量很大时,使用这种方法的工作量是繁重的。
例: char rat[5]={‘H’,’E’,’L’,’L’,’O’};
(2)用字符串常量对字符数组初始化 ,这时把字符数组当作字符串变量看待。
例: char panic[6]={“HELLO”);
这时存放在数组 panic中的字符除了 H,E,L,L,O之外还有结束标志 ‘/0’,因此与下面的初始化等价:
char panic[6]={‘H’,’E’,’L’,’L’,’O’};
注意 : 第二个说明语句中有 6 个字符 , 因此字符数组 panic 的长度是 6, 而字符串 “HELLO”的长度却是 5,不把 ‘/0’计算在内。
C语言也允许在用字符串初始化时省略花括号。
char panic[]=”HELLO”;
如果在说明语句中指定了数组的长度,那么其大小不得小于初始化字符串的长度。多余的元素位置被系统自动初始化为 0。实际上 ‘/0’就是 ASCII码为 0的字符 ,因此 ‘/0’和整数 0是一回事。
例: char posia[11]=”string”;
下面的初始化却是错误的 :
char neg[5]=”double arrow”; /初始化数据太多 /
3)字符数组两种不同用法举例
在前面已经说明 ,字符数组既可当作普通数组使用也可用于存储和处理字符串 .下面是对应两种用法的例子。
例 : 字符数组用法示例之一 ,当作普通数组。

#include<stdio.h>
#define SIZE 10
int main()
{
    char ary1[SIZE]={'P','L','O','T'};
    char ary2[SIZE];
    char ch;

    for(i=0;i<4;i++) /*输出数组 ary1*/
    printf("%c",ary1[i]);
    printf("/n请输入一行字符/ n");

    for(i=0;i<SIZE;i++) /*输入数组 ary2*/
    {
        scanf("%c",&ch);
        if(ch=='/n')
        break;
        ary2[i]=ch;
    }

    printf("/n");
    for(j=0;j<i;j++) /*输出数组 ary2*/
    printf("%c",ary2[j]);
    return 0;
}

 程序中为了处理数组使用了循环 ,并且使用了 ch,i,j等工作变量 ,增加了程序的负担 ,而且又缺乏灵活性 ,故这种方法很少使用。与下面完成同样功能的程序相比,本程序复杂多了。
例 : 字符数组用法之二 ,当作字符串。

#include<stdio.h>
#define SIZE 10
int main()
{
    char ary1[SIZE]="PLOT";
    char ary2[SIZE];
    printf("%s/n",ary1); /*输出数组 ary1*/
    printf("请输入一行字符 :/n");
    scanf("%s",ary2); /*输入数组 ary2*/
    printf("输入字符串是 :/n");
    printf("%s",ary2); /*输出数组 ary2*/
}

程序没有用循环 ,只是直接调用 scanf和 printf函数完成输入输出。程序之所以能够自动识别出字符串有几个字符,是因此规定了字符串必须以 ‘/0’作为结束 , 像 printf之类的函数输出字符串时一边检测一边输出 ,一旦碰到’/0’,便认为字符串已经结束 ,之后就停止工作。这样一来 ‘/0’对整个字符串来说至关重要了。一旦由于某种原因字符串的’/0’被改为别的值 ,字符串就无法终止 ,printf函数就不能正常工作了。
请注意 printf和 scanf函数处理字符串数组的特点。直接使用数组名作为参数。
例: printf(“%s/n”,ary1);
这种直接使用数组名的用法表示把字符串数组当作一个统一整体来处理,只适用于字符串,对别的类型的数组是不能这样用的。

字符串的输入输出
字符串的输入 字符串输出 字符串处理函数
scanf 函数
用带 %s格式符的 scnaf函数可以进行字符串的输入。在使用中要注意两个问题:一是 scanf函数读入的字符串开始于第一个非空白符,包括下一个空白符 (‘/ n’,’/t’,”)之前的所有字符,最后自动加上‘/ 0’。
例: char str[10];
scanf(“%s”,str);
输入: hello world
实际存入 str的只有 “hello”,前面的空格被忽略掉,而 “world”被留在输入缓冲区中等待下一次输入函数的读入。
二是要保证字符数组的长度足够大 ,能容纳下可能的最大输入串。
例: char t[5],s[10];
scanf(“%s”,t);
输入 :dingdong
则字符串 “dingdong”不仅存入了 t的空间 ,还侵占了 s的空间。
gets 函数
gets函数专门用于输入字符串 ,一般形式是 :
gets(字符数组名 );
其中 , 函数参数 ” 字符数组名 ” 规定了只能使用数组名而不能是字符串常量。与 scanf函数不同 ,gets函数将用户键入的换行符之前的所有字符 (包括 ‘/t’和 ”)存入字符数组 ,然后加上 ‘/0’,但换行符被丢掉。与 scanf函数相同的是 gets 函数也不检查用户输入字符串长度是否超过了字符数组的容纳能力,因此编程者要确保数组足够大。
例: char str[11];
gets(str);
输入 :I am a boy
字符串输出
printf 函数
用带 %s格式字符的 printf函数能进行字符串的输出。存放在字符数组中的字符串被全部输出,直至遇到 ‘/0’为止。
例: char msg[]=”T0 be or not to be”;
printf(“%s”,mag);
puts 函数
puts函数专门用于字符串输出。一般形式是:
puts(字符串 );
其中 , 参数 ” 字符串 ” 可以是字符串常量 , 也可以是字符串变量。 puts函数打印字符串的全部内容,直至遇到 ‘/0’为止 ,然后自动多打印一个 ‘/n’,起到换行的作用。而 printf函数无此功能。
到底应该使用 scanf和 printf还是使用 gets和 puts,没有一个绝对的标准。一般而言,当多种类型的混合输入输出时,选用 scanf和 printf; 当大量文字信息输入输出时,使用 gets和 puts,这两个函数要稍稍快一些。
字符串处理函数
介绍最有用又最常见的四个字符串处理函数: strlen、 strcat、 strcmp、 strcpy。这些函数的原型存放在string.h文件中,在程序中使用它们时别忘了用 #include命令包含 string.h文件。
strlen 函数
strlen函数测试字符串的实际长度(不包括 ‘/0’),并将该长度作为函数的值返回。函数参数“字符串”可以是字符串常量,也可以是字符变量一般形式是:
length=strlen(字符中)
例: “ABC” 长度为 3。
“abc/n” 长度为 4,而非 5,’/n’被看成一个字符。
“” 长度为 0,空字符串没有有效字符 ,所以长度为 0。
strcat 函数
strcat函数用于连结两个字符串。一般形式是:
strcat(字符串 1,字符串 2);
strcat函数把字符串 2连结在字符串 1的后面。其中,参数“字符串 1”必须是字符串变量 ,而 “字符串2”则可以是字符串常量或变量。
调用 strcat函数后, str1中字符后的 ‘/0’取消,只在新串最后保留一个’/0’。
注意 : strcat函数不检查字符串 1的空白位置是否装得下字符串 2。如果没有足够的空间,多余的字符将溢出至邻近的内存单元,破坏这些单元原来的内容。所以连结前应调用 strlen函数进行检验,确保不发生溢出。记住在检验时给长度加1,为新字符串的结束符 ‘/0’留一个位置。
例 : strcat函数示例。
static char str1[30]={“Pelple’s Republic of “};/注意空格/
static char str2[]={“China”};
printf(“%s”,strcat(str1,str2));
输出:
Pelple’s Republic of China
strcmp 函数
strcmp函数是比较两个字符串的大小 ,返回比较的结果。一般形式是:
i=strcmp(字符串,字符串 );
其中,字符串1、字符串2均可为字符串常量或变量; i 是用于存放比较结果的整型变量。比较结果是这样规定的:
①字符串 1小于字符串 2,strcmp函数返回一个负值 ;
②字符串 1等于字符串 2,strcmp函数返回零 ;
③字符串 1大于字符串 2,strcmp函数返回一个正值 ;那么 ,字符中的大小是如何比较的呢 ?来看一个例子。
实际上 ,字符串的比较是比较字符串中各对字符的 ASCII码。首先比较两个串的第一个字符,若不相等,则停止比较并得出大于或小于的结果;如果相等就接着比较第二个字符然后第三个字符等等。如果两上字符串前面的字符一直相等 ,像 “disk”和 “disks” 那样 , 前四个字符都一样 , 然后比较第五个字符 , 前一个字符串”disk”只剩下结束符 ‘/0’,后一个字符串 “disks”剩下 ‘s’,’/0’的 ASCII码小于 ‘s’的 ASCII码 ,所以得出了结果。因此无论两个字符串是什么样, strcmp函数最多比较到其中一个字符串遇到结束符 ‘/0’为止,就能得出结果。
注意:字符串是数组类型而非简单类型,不能用关系运算进行大小比较。
if(“ABC”>”DEF”) /错误的字符串比较 /
if(strcmp(“ABC”,”DEF”) /正确的字符串比较 /
strcpy 函数
strcpy函数用于实现两个字符串的拷贝。一般形式是:
strcpy(字符中 1,字符串 2)
其中 ,字符串 1必须是字符串变量 ,而不能是字符串常量。 strcpy函数把字符串 2的内容完全复制到字符串 1中 ,而不管字符串 1中原先存放的是什么。复制后,字符串 2保持不变。
例 :
注意 ,由于字符串是数组类型 ,所以两个字符串复制不通过赋值运算进行。
t=s; /错误的字符串复制 /
strcpy(t,s); /正确的字符串复制 /

综合举例
例 : 输入一行字符 ,统计其中有多少个单词,单词之间用空格分隔开。
分析:程序中设置变量i作为循环变量,num用来统计单词个数,word作为判别是否单词的标志,若word=0表示未出现单词,如出现单词word置1。
单词的数目可以由空格出现的次数决定(连续的若干个空格作为出现一次空格;一行开头的空格不在内)。

#include "stdio.h"
int main()
{
    char string[81];
    int i,num=0,word=0;
    char c;
    gets(string);
    for(i=0,(c=string[i])!='/0',i++)
    if(c=='') word=0;
    else if(word==0)
    {
        word=1;
        num++;
    }
    printf("There are %d words in the line/n",num);
    return 0;
}

运行结果:
I am a boy.
There are 4 words in the line
例: 编一个程序,将两个字符串s1和s2比较,如果s1>s2,输出一个正数;s1=s2,输出0;s1

#include <stdio.h>
int main()
{
    int i,resu;
    char s1[100],s2[100];
    printf("请输入字符串1:/n");
    gets(s1);
    printf("请输入字符串2:/n");
    gets(s2);
    i=0;
    while((s1[i]==s2[i])&&(s1[i]!='/0')) i++;
    if(s1[i]=='/0'&&s2[i]=='/0') 
        resu=0;
    else
        resu=s1[i]-s2[i];
    printf(" %s%s比较结果是%d.",s1,s2,resu);
    return 0;
}

运行结果:
请输入字符串1:
aid
请输入字符串2:
and
aid与and比较结果是-5。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值