字符串函数
字符串要录入,就要使用函数。
先看看gets()和puts(s)
gets()读入的是一行,遇到换行符停止。然后末尾添加一个\0作为字符串存储起来。puts()和gets()是配对使用的,puts()输出内容,注意的是puts()输出完之后会自动换行。
但是这个函数有一个问题,gets并不限制大小,会造成缓冲区溢出。多余的字符会擦掉未知内存的空间内容,造成程序问题。所以要特别小心。
因为gets的问题,就有了fgets()作为替代,fgets会限制输入的大小,但是使用上稍有麻烦。char *fgets(char *s, int size, FILE *stream),看函数原型变质,需要三个参数,这里的FILE *stream 可以用stdin代替作为键盘输入。这个函数保证了安全性。但是使用上略显繁琐了。和fgets配对使用的是 fputs.同样看函数原型 int fputs(const char *s, FILE *stream) 同样的这里的FILE *stream可以用stdout作为输出。注意的是fputs并不会输出\n.另外fgets()会把读到的\n也储存在数组中,即以\n\0结尾。来写个程序验证下
12 int main(int argc, const char *argv[])
13 {
14 ¦ char arr[10] ;
15
16 ¦ fgets(arr,10,stdin);
17 ¦ fputs(arr,stdout);
18 ¦
19 ¦ return 0;
20 }
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhfs@ubuntu:~/class_practice$ ./scanf_two_arr
he
he
这里就看出来了,当输入多个h的时候,因为超出了10的范围,同时米有遇到\n所以输出了9个h同时没有换行,当录入he的时候因为没有超出范围也把\n采集了,输出的时候也输出了\n.
哈,下面有一个比较有意思的地方,这个fgets的返回值 在不出错的情况下返回的是char *,出错或者读到文件末尾返回的是NULL,如果一个文档为空那存储的只有一个\n,直接回车不录入。下面用程序来验证下
int main(int argc, const char *argv[])
13 {
14 ¦ char arr[10] ;
15
16 ¦ char * p = NULL;
17
18 ¦ while((p = fgets(arr,10,stdin)) != NULL && arr[0] != '\n')
19 ¦ {
20 ¦ ¦ fputs(arr,stdout);
21 ¦ }
22
23 ¦ printf("arr = %p\n",arr);
24 ¦ printf("fgets = %p\n",p);
25
26 ¦ return 0;
27 }
sdfsdakjfhskdjhfksjdhfkjsdhfkjsdhkfjhsd
sdfsdakjfhskdjhfksjdhfkjsdhfkjsdhkfjhsd
arr = 0xbfa87262
fgets = 0xbfa87262
哈,返回值验证成功。另外用返回值验证了如何输入一个较长的字符,超出数组范围。会分段一起输出。这里奇怪的是arr只有10个字符的空间,却能存储并输出这么长的一段。查资料得知,录入的数据都被存储在缓冲区,按下回车后,从缓冲区每次fgets 10个字符,fputs把fgets采集到的字符也发送到另外一个缓冲区,按下回车后一起输出。注意的是最后存储了\n.分段的每段是。。。。。。\0 。。。。。\0最后是。。。。。。。\n\0.这里的小问题是有可能你并不想要这个\n .好处是\n可以判断是否读取了整行。
如果不想要\n那可以在程序中增加代码删除\n
12 int main(int argc, const char *argv[])
13 {
14 ¦ char arr[10] ;
15 ¦ int i = 0;
16 ¦ char * p = NULL;
17
18 ¦ while((p = fgets(arr,10,stdin)) != NULL && arr[0] != '\n')
19 ¦ {
20 ¦ ¦ for(i = 0; i < 10; i++ )
21 ¦ ¦ {
22 ¦ ¦ ¦ if(arr[i] == '\n')
23 ¦ ¦ ¦ ¦ arr[i] = '\0';
24 ¦ ¦ }
25 ¦ ¦ fputs(arr,stdout);
26 ¦ }
27
28 ¦ printf("arr = %p\n",arr);
29 ¦ printf("fgets = %p\n",p);
30
31 ¦ return 0;
32 }