C语言字符串

在c语言中,字符串是用字符数组来存储的(并不像c++或者java等语言中有单独的string类型),

存放时在字符串的末尾增加了表示字符串结束的标志字符'\\0'

字符串虽然是按组成字符串的各个字符存储在数组的各个元素中,但其往往表示一个整体信息,将其分离成单个字符是没有意义的,所以往往也是将其作为一个整体进行处理。

下面就几个方面对字符串进行介绍。

1. 字符串数组的定义与使用

#include "stdio.h"

void main()

{

char my_string[15];

printf("input a string:");

scanf("%s",my_string);

printf("%s",my_string);

}

输入是abc124a时输入输出如下表示:

input a string:abc124a

abc124a

当输入是123 abc时输入输出如下表示:

input a string:123 abc

123

注意:把一个字符数组看成字符串后,可以直接使用%s来输入输出,后面直接使用数组名。

用%s读入时,表示需要读入一个字符串到字符数组中,遇到第一个空格或回车,读入即停止。

读入时还需要特别注意的是定义的字符数组的长度应该要大于读入数据的长度。

用%s输出时,要注意的是输出的是字符串的实际长度的那些字符,而不是输出定义时的字符数组的长度。如:

#include "stdio.h"

void main()

{

char my_str[5];

int i;

my_str[4]='K';

printf("input a string:");

scanf("%s", my_str);

printf("%s", my_str);

}

输入输出如下:

input a string:2q

2q

这个例子中,

my_str[]数组的第五个元素是’k’字符,但是读入这个字符串时只用到了2个元素,即

my_str[0]=2

my_str[1]=q

而%s输出时仅仅输出了2q这两个字符,那么字符串输出是怎么知道结束了的呢?

这里会使用到一个默认的字符串结束标志字符’\\0’,即此时读入时,会在末尾自动加上

my_str[2]=’\\0’,所以输出时从字符串的头即0号元素即数组的首地址一直输出到’\\0’为止,并且这个结束字符本身不会输出。

再有,

#include "stdio.h"

void main()

{

char my_str[30]="abab adda";

int i;

printf("%s\\n",my_str);

for(i=0;i<30;i++)

{

printf("%c",my_str[i]);

}

}

输入输出如下:

abab adda

abab adda

需要注意的是,这个字符串中有个空格字符,会正常输出,不会截断。

对比下面一个例子。利用%s输入。

#include "stdio.h"

void main()

{

char my_str[30];

scanf("%s",my_str);

printf("%s",my_str);

}

输入输出如下:

abab adda

abab

因为%s读入遇到空格就结束了。

2.常用字符类型函数

字符类型函数分为两类:类型判断类函数和类型转换类函数。类型判断类函数是用来测试一个字符是否属于某一类型,如是否为字母,数字等。

当字符属于函数所指定的类型时,函数返回真值1,否则返回值0.

类型转换类函数包括两个函数,一个是将字母字符由大写转换成小写,另一个是将字母字符由小写转换成大写。

常用的字符类型函数如下:(使用时,需要引用头文件  )

函数原型函数功能描述

int isalunm(int ch)检查ch是否是字母或数字

int isalpha(int ch)检查ch是否是字母

int isdigit(int ch)检查ch是否是数字

int islower(int ch)检查ch是否是小写字母

int issupper(int ch)检查ch是否是大写字母

int iscntrl(int ch)检查ch是否是控制字母

int tolower(int ch)将大写字符ch转换成小写字符

int toupper(int ch)将小写字符ch转换成大写字符

int isalunm(int ch)检查ch是否是字母或数字

3.字符串操作函数。  需要引用头文件

先列出主要的简介,具体介绍见下文。

strtok()字符串分割函数

strstr()字符串查找函数

strspn()字符查找函数

strrchr()定位字符串中最后出现的指定字符

strpbrk()定位字符串中第一个出现的指定字符

strncpy()复制字符串

strncat()字符串连接函数

strncasecmp()字符串比较函数(忽略大小写)

strlen()字符串长度计算函数

strdup()复制字符串

strcspn()查找字符串

strcpy()复制字符串

strcoll()字符串比较函数(按字符排列次序)

strcmp()字符串比较函数(比较字符串)

strchr()字符串查找函数(返回首次出现字符的位置)

strcat()连接字符串

strcasecmp()字符串比较函数(忽略大小写比较字符串)

rindex()字符串查找函数(返回最后一次出现的位置)

index()字符串查找函数(返回首次出现的位置)

toupper()字符串转换函数(小写转大写)

tolower()字符串转换函数(大写转小写)

toascii()将整数转换成合法的ASCII码字符

strtoul()将字符串转换成无符号长整型数

strtol()将字符串转换成长整型数

strtod()将字符串转换成浮点数

gcvt()将浮点型数转换为字符串(四舍五入)

atol()将字符串转换成长整型数

atoi()将字符串转换成整型数

atof()将字符串转换成浮点型数

void *memset(void *dest, int c, size_t count);

将dest前面count个字符置为字符c. 返回dest的值.

void *memmove(void *dest, const void *src, size_t count);

从src复制count字节的字符到dest. 如果src和dest出现重叠, 函数会自动处理. 返回dest的值.

void *memcpy(void *dest, const void *src, size_t count);

从src复制count字节的字符到dest. 与memmove功能一样, 只是不能处理src和dest出现重叠. 返回dest的值.

void *memchr(const void *buf, int c, size_t count);

在buf前面count字节中查找首次出现字符c的位置. 找到了字符c或者已经搜寻了count个字节, 查找即停止.

操作成功则返回buf中首次出现c的位置指针, 否则返回NULL.

void *_memccpy(void *dest, const void *src, int c, size_t count);

从src复制0个或多个字节的字符到dest. 当字符c被复制或者count个字符被复制时, 复制停止.

如果字符c被复制, 函数返回这个字符后面紧挨一个字符位置的指针. 否则返回NULL.

int memcmp(const void *buf1, const void *buf2, size_t count);

比较buf1和buf2前面count个字节大小.

返回值< 0, 表示buf1小于buf2;

返回值为0, 表示buf1等于buf2;

返回值> 0, 表示buf1大于buf2.

int memicmp(const void *buf1, const void *buf2, size_t count);

比较buf1和buf2前面count个字节. 与memcmp不同的是, 它不区分大小写.

返回值同上.

size_t strlen(const char *string);

获取字符串长度, 字符串结束符NULL不计算在内.

没有返回值指示操作错误.

char *strrev(char *string);

将字符串string中的字符顺序颠倒过来. NULL结束符位置不变.

返回调整后的字符串的指针.

char *_strupr(char *string);

将string中所有小写字母替换成相应的大写字母, 其它字符保持不变.

返回调整后的字符串的指针.

char *_strlwr(char *string);

将string中所有大写字母替换成相应的小写字母, 其它字符保持不变.

返回调整后的字符串的指针.

char *strchr(const char *string, int c);

查找字符c在字符串string中首次出现的位置, NULL结束符也包含在查找中.

返回一个指针, 指向字符c在字符串string中首次出现的位置, 如果没有找到, 则返回NULL.

char *strrchr(const char *string, int c);

查找字符c在字符串string中最后一次出现的位置, 也就是对string进行反序搜索, 包含NULL结束符.

返回一个指针, 指向字符c在字符串string中最后一次出现的位置, 如果没有找到, 则返回NULL.

char *strstr(const char *string, const char *strSearch);

在字符串string中查找strSearch子串.

返回子串strSearch在string中首次出现位置的指针. 如果没有找到子串strSearch, 则返回NULL. 如果子串strSearch为空串, 函数返回string值.

char *strdup(const char *strSource);

函数运行中会自己调用malloc函数为复制strSource字符串分配存储空间, 然后再将strSource复制到分配到的空间中. 注意要及时释放这个分配的空间.

返回一个指针, 指向为复制字符串分配的空间; 如果分配空间失败, 则返回NULL值.

char *strcat(char *strDestination, const char *strSource);

将源串strSource添加到目标串strDestination后面, 并在得到的新串后面加上NULL结束符. 源串strSource的字符会覆盖目标串strDestination后面的结束符NULL. 在字符串的复制或添加过程中没有溢出检查, 所以要保证目标串空间足够大. 不能处理源串与目标串重叠的情况.

函数返回strDestination值.

char *strncat(char *strDestination, const char *strSource, size_t count);

将源串strSource开始的count个字符添加到目标串strDest后. 源串strSource的字符会覆盖目标串strDestination后面的结束符NULL. 如果count大于源串长度, 则会用源串的长度值替换count值. 得到的新串后面会自动加上NULL结束符. 与strcat函数一样, 本函数不能处理源串与目标串重叠的情况.

函数返回strDestination值.

char *strcpy(char *strDestination, const char *strSource);

复制源串strSource到目标串strDestination所指定的位置, 包含NULL结束符. 不能处理源串与目标串重叠的情况.

函数返回strDestination值.

char *strncpy(char *strDestination, const char *strSource, size_t count);

将源串strSource开始的count个字符复制到目标串strDestination所指定的位置. 如果count值小于或等于strSource串的长度, 不会自动添加NULL结束符目标串中, 而count大于strSource串的长度时, 则将strSource用NULL结束符填充补齐count个字符, 复制到目标串中. 不能处理源串与目标串重叠的情况.

函数返回strDestination值.

char *strset(char *string, int c);

将string串的所有字符设置为字符c, 遇到NULL结束符停止.

函数返回内容调整后的string指针.

char *strnset(char *string, int c, size_t count);

将string串开始count个字符设置为字符c, 如果count值大于string串的长度, 将用string的长度替换count值.

函数返回内容调整后的string指针.

size_t strspn(const char *string, const char *strCharSet);

查找任何一个不包含在strCharSet串中的字符 (字符串结束符NULL除外) 在string串中首次出现的位置序号.

返回一个整数值, 指定在string中全部由characters中的字符组成的子串的长度. 如果string以一个不包含在strCharSet中的字符开头, 函数将返回0值.

size_t strcspn(const char *string, const char *strCharSet);

查找strCharSet串中任何一个字符在string串中首次出现的位置序号, 包含字符串结束符NULL.

返回一个整数值, 指定在string中全部由非characters中的字符组成的子串的长度. 如果string以一个包含在strCharSet中的字符开头, 函数将返回0值.

char *strspnp(const char *string, const char *strCharSet);

查找任何一个不包含在strCharSet串中的字符 (字符串结束符NULL除外) 在string串中首次出现的位置指针.

返回一个指针, 指向非strCharSet中的字符在string中首次出现的位置.

char *strpbrk(const char *string, const char *strCharSet);

查找strCharSet串中任何一个字符在string串中首次出现的位置, 不包含字符串结束符NULL.

返回一个指针, 指向strCharSet中任一字符在string中首次出现的位置. 如果两个字符串参数不含相同字符, 则返回NULL值.

int strcmp(const char *string1, const char *string2);

比较字符串string1和string2大小.

返回值< 0, 表示string1小于string2;

返回值为0, 表示string1等于string2;

返回值> 0, 表示string1大于string2.

int stricmp(const char *string1, const char *string2);

比较字符串string1和string2大小,和strcmp不同, 比较的是它们的小写字母版本.

返回值与strcmp相同.

int strcmpi(const char *string1, const char *string2);

等价于stricmp函数, 只是提供一个向后兼容的版本.

int strncmp(const char *string1, const char *string2, size_t count);

比较字符串string1和string2大小,只比较前面count个字符. 比较过程中, 任何一个字符串的长度小于count, 则count将被较短的字符串的长度取代. 此时如果两串前面的字符都相等, 则较短的串要小.

返回值< 0, 表示string1的子串小于string2的子串;

返回值为0, 表示string1的子串等于string2的子串;

返回值> 0, 表示string1的子串大于string2的子串.

int strnicmp(const char *string1, const char *string2, size_t count);

比较字符串string1和string2大小,只比较前面count个字符. 与strncmp不同的是, 比较的是它们的小写字母版本.

返回值与strncmp相同.

char *strtok(char *strToken, const char *strDelimit);

在strToken 串中查找下一个标记, strDelimit字符集则指定了在当前查找调用中可能遇到的分界符.

返回一个指针, 指向在strToken中找到的下一个标记. 如果找不到标记, 就返回NULL值. 每次调用都会修改strToken内容, 用NULL字符替换遇到的每个分界符.

至此,字符串操作差不多就介绍完了。

上文还有一个疑问,就是如何读入例如 I love you 这样断断续续的字符串。这个问题我之后将会去重新学习一下输入输出语句,到时候再和大家一同分享。

下面,以一简单的实例介绍本篇博客。

问题描述:判断一个由a~z这26个字符组成的字符串中哪个字符出现的次数最多。

输入:第一行是测试数据的组数n(n<=10),每组测试数据占一行,不超过80字符且非空、

输出:一行输出包括出现次数最多的字符和该字符出现的次数,中间是一个空格,如果次数相同,输出ASCII码最小的字符。

由于比较简单,我就直接上代码了。不懂的相信看了代码也能明白的、

#include "stdio.h"

void main()

{

char str[81];

int count[26], i, k, n;  //26个字母的计数器

scanf("%d",&n);   //测试数据组数

while (n-->0)

{

scanf("%s",str);   //读入字符串

for (i=0; i<26; i++)   //初始化字符串,个数清0

{

count[i] = 0;

}

i = 0;

while ( str[i] != '\\0')

{

count[str[i] - 'a']++;         //对出现的字符计数

i++;

}

k = 0;

for (i=1; i<26; i++)

{

if (count[i] > count[k])

{

k = i;                         //查找次数最多的

}

}

printf("%c %d\\n", 'a'+k,count[k]);

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容