在c语言中读取字符串有多种方法,比如scanf() 配合%s使用,但是这种方法只能获取一个单词,即遇到空格等空字符就会返回。如果要读取一行字符串,比如:
I love BIT
这种情况,scanf()就无能为力了。这时我们最先想到的是用gets()读取.
gets()函数从标准输入(键盘)读入一行数据,所谓读取一行,就是遇到换行符就返回。gets()函数并不读取换行符’\n’,它会吧换行符替换成空字符’\0’,作为c语言字符串结束的标志。
gets()函数经常和puts()函数配对使用,puts()函数用于显示字符串,并自动在字符串后面添加一个换行标志’\n’
#include <string.h> #include <stdio.h> //读取带有空格的字符串并且按空格分割 int main() { char str[1000]; const char *d = " "; while (gets(str) != NULL) { printf("%s\n", str); char *p; p = strtok(str, d); while(p) { printf("%s\n", p); p = strtok(NULL, d); } } return 0; }比如:
我们定义了一个数组char src[5],这时候我们调用gets(src),来从标准输入读取字符串,我们看到gets()函数的参数为数组名,我们都知道,数组名就相当于一个指针,也就是数组的首地址。这时如果我们的输入大于5个字符,比如 I love BIT,gets()函数会从src所指地址开始,依次填入每个字符,但是src只分配了5个字节的空间,填满这五个空间后,gets()函数就会访问未被分配的内存空间,如果这片空间已经存有数据,这时程序就会发生错误,而中断。
正式由于gets()函数的这个缺陷,在C99标准中,已经不再建议使用gets()函数,而在C11中更是直接抛弃了这个函数。
其实我们可以用c语言中的fgets()函数来代替gets()
我们先看一下函数原型声明:
char *fgets(char *buf, int bufsize, FILE *stream);
注意一下第二个参数bufsize,这个参数就限制了读取的字符的个数,这就可以解决gets()函数的缺陷。
可以看一个简单的小例子:
#include <stdio.h> #include <stdlib.h> #define LEN 6 int main(int argc,char* argv[]) { char src[LEN]; printf("please enter:\n"); fgets(src,LEN,stdin); printf("your enter is:\n"); fputs(src,stdout); }在这个程序中,我把数组的长度设置为6,先看一组输入和输出: please enter: zhan you enter is: zhan Press any key to continue 输入为zhan和回车(’\n’),一共五个字符,fgets会读取这五个字符,然后在末尾添加字符串结束标志’\0’; 我们知道fputs()函数并不会自动添加换行,但是输出结果却换行输出了Press any….,这就说明了fgets()函数是会读取换行符的。
在看一组输入输出: please enter: zhang you enter is: zhangPress any key to continue
这次我输入了zhang和回车换行,fgets函数依然是读取5个字符(LEN-1个),这时fgets()读入zhang,已经是五个字符了,所以回车换行并不会读入,最后fgets()添加字符串结束标志’\0’,所以我们看到输出时,Press any…并没有换行输出,而是和zhang在同一行。