它们最根本的区别是在内存中的存储区域不一样 !
字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限 ! 而常量区的字符串(也包括其他数据)只有读取权限 ! 没有写入权限。
因为 常量区没有写入权限,所以 当使用 strtok 函数处理 指针字符串时,
char * str = "123s 123s 13s3";
strtok(str,s);
这样就必然会出错。
转载请注明出处
1.scanf()
所在头文件:stdio.h
语法:scanf(“格式控制字符串”,变量地址列表);
接受字符串时:scanf(“%s”,字符数组名或指针);
2.gets()
所在头文件:stdio.h
语法:gets(字符数组名或指针);
两者在接受字符串时:
1.不同点:
scanf 不能接受空格、制表符Tab、回车等;
而gets 能够接受空格、制表符Tab和回车等;
scanf :当遇到回车,空格和 tab键 会自动在字符串后面添加’\0’,但是回车,空格和tab键仍会留在输入的缓冲区中。
gets:可接受回车键之前输入的所有字符,并用’\0’替代 ‘\n’.回车键不会留在输入缓冲区中
#include
int main()
{
char a[10];
scanf("%s",a);
printf("%s\n",a);
return 0;
}
从键盘输入字符串 asd df时,遇到空格,scanf()就认为输入结束了,所以a中存放的字符串是 ‘asd\0’。
#include
int main()
{
char a[10];
gets(a);
printf("%s\n",a);
return 0;
}
从键盘输入字符串 asd df时,gets()遇到’\n’才认为是结束输入了,所以a中存放的是’asd df\0’。
实例分析:
#include
int main()
{
char a[10],b[10];
char c,d;
scanf("%s",a);
printf("a中保存的字符串为:%s\n",a);
c=getchar();
printf("c中保存的字符为:%c ",c);
gets(b);
printf("b中保存的字符串为:%s\n",b);
d=getchar();
printf("d中保存的字符为:%c",d);
return 0;
}
输入asdf回车,因为scanf会将回车保留在缓冲区中,所以回车会紧接着被c取得而不需要再额外输入,所以a中存储的是’asdf\0’,字符c=’\n’。结果如下:
接着输入as df回车,因为gets会将’\n’替换成’\0’,所以b字符串中保留的是’as df\0’,并且还是要继续输入d的值:
最后输入d的值:
相同点:
两者都属于stdio.h这个头文件
都能输出字符串
不同点:
puts()在输出字符串时会将’\0’自动转换成’\n’进行输出,也就是说,puts方法输出完字符串后会自动换行。
字符串是一系列连续的字符的组合,要想在内存中定位一个字符串,除了要知道它的开头,还要知道它的结尾。找到字符串的开头很容易,知道它的名字(字符数组名或者字符串名)就可以;然而,如何找到字符串的结尾呢?C语言的解决方案有点奇妙,或者说有点奇葩。
在C语言中,字符串总是以’\0’作为结尾,所以’\0’也被称为字符串结束标志,或者字符串结束符。
'\0'是 ASCII 码表中的第 0 个字符,英文称为 NULL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在C语言中唯一的作用就是作为字符串结束标志。
C语言在处理字符串时,会从前往后逐个扫描字符,一旦遇到’\0’就认为到达了字符串的末尾,就结束处理。’\0’至关重要,没有’\0’就意味着永远也到达不了字符串的结尾。
由 " " 包围的字符串会自动在末尾添加 ‘\0’ 。例如,“abc123” 从表面看起来只包含了 6
个字符,其实不然,C语言会在最后隐式地添加一个’\0’,这个过程是在后台默默地进行的,所以我们感受不到。