将字符串赋给数组:字符串储存在静态存储区(static memory)中,程序运行后,为数组分配内存,再将字符串拷贝到数组中。
将字符串赋给指针:字符串储存在静态存储区(static memory)中,程序运行后,为指针分配内存,再将字符串首元素的地址拷贝到指针分配到的内存中。
如果只显示字符串,可以用指针存储,这样对内存的利用率比数组高。
如果要修改字符串,可以用数组存储,这样对于修改的只是字符串的副本。//至于为什么,你猜。
3.字符串输入与输出
scanf():大部分scanf函数应用,将从第一个非空白字符作为字符串的开始,以第一个空白字符结束。
gets():读取一行,直到检测出换行符,之后删掉换行符,加上’\0’。但是只能检测出字符串的开头,不知道字符串何时结尾,故不清楚字符串的长度,如果字符串过长,会产生缓冲区溢出(buffer overflow)。//C99标准建议不使用,C11标准扔,但是为了兼容以前的代码,大部分编译器仍然承认这一函数。
fgets():过去通常作为gets的替代函数,一般用于读取文件,函数原型:char *fgets(char *str, int n, FILE *stream),从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。若想从键盘键入字符串,则需要运用fgets函数时,第三个参数修改为stdin(标准输入)。一般读取n-1个字符或者遇到第一个换行符为止。//换行符也写入str所指向的字符串内。
gets_s():第二个参数为最大字符数,若输入不超过最大字符数,使用和gets一样。//C11标准可选。
s_gets():自己定义一个读取一行,丢弃换行符,并丢弃超出规定大小部分。用来替代gets。
char *s_gets(char *st,int n){
char *ret_val;
int i = 0;
ret_val = fgets(st,n,stdin);//下文所出现的都是已经输入完成的内容
if(ret_val){//fgets没有读取到文件结尾或者读取错误
while(st[i] != '\n' && st[i] != '\0')//如果检测本元素检测出不是换行符或者字符串结尾空字符
i++; //继续检验下一个元素
if(st[i] == '\n') //如果是换行符
st[i] = '\0'; //则把换行符换成空字符,标志着读取结束,且字符串最后\n\0\0...变成\0\0...
else //如果字符串后一个字符是空字符
while(getchar() != '\n') //如果超出最大字符数,超出部分会留在缓存区,getchar可以清空缓存区剩余部分
continue;
}
return ret_val;
}
puts():只需要用字符串地址作为参数,当检测到第一个空字符时,停止输出。输出显示字符串时,在最后自动增加一个换行符。
fputs():具有的功能是向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’),与fgets成对使用,是puts针对于文件的版本,但是不会在输出字符串末尾加上换行符。函数原型是:char *fputs(char *str,FILE *stream),若要将结果显示在显示器上,则需要应用函数的时候,将第二个参数改为stout(标准输出)。
4.字符串函数
strlen():统计字符串长度。
strcat():用于拼接字符串,将第二个字符串连接到第一个字符串末尾,并改变第一个字符串,第二个字符串不变,函数返回第一个字符串地址。
strncat():strcat无法检测第一个数组能否容纳第二个字符串,所以该函数相对于strcat()函数增加了第三个参数,即最大添加字符数。
strcmp():比较两个字符串中第一个空字符前的字符串,若参数相同,则返回0,反之,返回非零值。当前者比后者字符多或者在字母表中靠前,则返回正数,反之返回负数。
strncmp():相比strcmp()函数,其增加了第三个参数,起作用是比较两个字符串的前多少个字符,若第三个参数为5,则比较两字符串前5位是否相同。
strcpy():将第二个参数(源字符串)拷贝到第一个参数(目标字符串),返回第一个参数的的值,即一个字符的地址。
strncpy():与strncat类似,第三个参数为最大拷贝字符数。
sprintf():可以把多个元素整合成一个字符串,类似于printf()函数,例:sprintf(a,"%s %s %d",b,c,d),其作用是将b,c,d按转换格式存储到a中。//唯一一个函数声明在stdio.h头文件中。
其他字符串函数:
char *strchr(const char * s,int c);
/*如果过s字符串包含c字符,该函数返回指向s字符串首次
出现的c字符的指针,若未找到则返回空指针*/
char *strpbrk(const char * s1, const char * s2);
/*若所s1字符中包含s2字符串中的任意字符,该函数返回指向s1字符串首位置
的指针;如果s1字符串中未找到任何s2字符串中的字符,则返回空字符串*/
char *strrchr(const char * s,int c);
/*该函数返回s字符串中c字符的最后一次出现的位置。如果未找到,返回空指针*/
char *strstr(const char * s1,const char * s2);
/*该函数返回指向s1字符串中s2字符串出现的首位置。如果s1中没有找到s2,则返回空指针*/
size_t strlen(const char * s)
/*该函数返回s字符串中的字符数*/
//码字不易!!!!
5.字符串示例——字符串排序
#include<stdio.h>
#include<string.h>
#define SIZE 81
#define LIM 20 /*可读入的最多行数*/
#define HALT "" /*空格字符串停止输入*/
void stsrt(char *strings[], int num);
char *s_gets(char *st, int n);
int main()
{
char input[LIM][SIZE]; /*存储输入的数组*/
char *ptstr[LIM]; /*内含指针变量的数组,均指向每一行的首地址*/
int ct = 0; /*输入计数*/
int k; /*输出计数*/
printf("input up to %d lines,and i will sort them.\n", LIM);
printf("to stop,press the enter key at a line's start.\n");
/*此处只需要直接指向字符数组某一行的首地址,便可以实现怼字符串的输入*/
while (ct < LIM&&s_gets(input[ct], SIZE) != NULL&&input[ct][0] != '\0')
{
ptstr[ct] = input[ct]; /*设置指针指向字符串*/
ct++;
}
stsrt(ptstr, ct);
puts("\nhere's the sorted list:\n");
for (k = 0; k < ct; k++)
puts(ptstr[k]); /*排序后的指针*/
return 0;
}
/*字符串-指针-排序函数*/
void stsrt(char *strings[], int num)
{
char *temp;
int top, seek;
for(top=0;top<num-1;top++)
for(seek=top+1;seek<num;seek++)//遍历top和top后的关系
if (strcmp(strings[top], strings[seek]) > 0)//通过strcmp把top和top后的字符串中每个字符作对比,达到字母排序的效果
{
temp = strings[top];
strings[top] = strings[seek];
strings[seek] = temp;//简单的位置调换
}
}
char *s_gets(char *st, int n)
{
char *ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (st[i] != '\n'&&st[i] != '0')
i++;
if (st[i] == '\n') st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}