一、字符串常量
位于一对双引号中的任意字符,如果字符串文字中间没有间隔或间隔是空格符,ANSI C会将它串起来。例如
char str[50]="hello" "wo" "you!"; 和 char st[50]="wo,nihao!"; 都是字符串。
二、字符串数组及其初始化
定义一个字符串数组时,必须要让编译器知道它需要多大空间。
count char str[50]="hello, I am asfsvdx!"; count 表示这个字符串不可以改变。相比下面的初始化很简短:
count char str1[50]={'h','e','l','l','o','\0'};
注意标示结束的空字符,如果没有‘\0’,它就是一个字符数组,而不是一个字符串。
指定数组大小时,一定要确保数组元素比字符串长度至少多1,用于存放空字符。未被使用的空间会被默认为‘\0’。
也可以让编译器决定数组大小:
count char str2[]="asfawsgasdf";
字符数组名也是数组首元素地址。
str2==&str2[0] *str2='a' *(str2+1)==str2[1] =='s'
的确,也可以用 指针符号创建字符串 例如:
count char *str[]="asfasfgsdg";
三、数组与指针
char str1[]="I love you!";// 初始化存放字符串的数组
char *str="I love you!"; //初始化一个指向字符串的指针
他们主要的差别在于 str1是一个常量,而指针 str 是一个变量。
首先,两者都可以使用数组符号:
for(int i=0;i<6;i++){ for(int i=0;i<6;i++){
putchar(str1[i]); putchar(str[i]);
} }
输出: I love I love
其次,两者都可以使用指针加法:
for(int i=0;i<6;i++){ for(int i=0;i<6;i++){
putchar(*(str1+i)); putchar(*(str+i));
} }
输出: I love I love
但是只有指针可以使用增量运算
while(*str)
putchar(*(str++));
输出: I love you!
如果希望str1[] 和 str 相同 ,可以 str=str1;//str指向数组str1
数组元素是变量,但是数组名不是变量。
四、字符串和指针
指针str 和 copy 存放在00AFFA8C和00AFFA80两个位置,但是他们都存放了这个字符串的地址,因此,字符串本身没有被复制,只是让第二个指针也指向同一个字符串。
五、字符串函数
1、gets()
它从系统的标准输入设备(通常是键盘)获得一个字符串,字符串结束标志是换行符\n ,读取到换行符后会丢弃它,参数是字符串的地址,注意,数组名当然也是一个地址。它返回一个指向char的指针。
2、fgets()
它需要第二个参数来说明最大读入字符数,这样不会造成溢出的问题。如果这个参数是n,fgets()就会读取最多n-1个字符,或者读取到换行符结束。如果读到换行符,会把它存到字符串里。他还需要第三个参数表示读哪一个文件。
注意:由于gets()不检查目标数组是否能够容纳输入,所以很不安全。蠕虫病毒就是利用这一缺点。对于重要的编程应用fgets()而不是gets();
3、puts()
使用很简单,只需要给出字符串参数的地址。例如
#define STR "I am boy."
char str1[80]="An array was initialized to me.";
const char *str2="A pointer was initialized to me.";
puts("I am an argument to puts().");
puts(STR);
puts(str1);
puts(str2);
puts(&str1[5]);
puts(str2+4);
输出:
I am an argument to puts().
I am boy.
An array was initialized to me.
A pointer was initialized to me.
ray was initialized to me.
inter was initialized to me.
puts()显示字符串后自动加换行符。表达式的地址正是函数输出字符的起点。并在输出‘\0’停止。
4、fputs()
第二个参数是说明要写的文件。fputs并不会自动加换行符。
5、strlen()
可以得到字符串的长度。读到‘\0’停止。
6、strcat()
函数有两个参数,将第二个字符串的拷贝添加到第一个末尾,从而使第一个成为一个新的字符串,函数返回添加的字符串的第一个字符的地址。
7、strncat()
strcat()并不检查第一个数组能否容纳第二个字符串。可能会出现溢出,所以strncat()第三个参数来指明最多允许添加的字符数。
8、strcmp()
可以比较两个字符串的内容是否相同,如果相同返回0。它的参数比较的是字符串而不是数组和字符,比如“asf”“A”,而不是‘A’。
函数的返回值:
返回的是第一个不同的字符的ASCII值的差。相等返回0.
9、strncmp()
第三个参数可以指定比较前多少个字符。
10、strcpy()、strncpy()
可以复制字符串,要注意,并不是真的复制了字符串,而是复制了指向这个字符串的地址。
strncpy也是比较谨慎的选择,提供第三个参数,表示需要复制的字符数。如果大于第一个数组的大小,就停止复制。