gets()
gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with a null byte ('\0'). No check for buffer overrun is performed (see BUGS below).
--gets()从标准输入中读进缓冲区通过s指向知道出现另一新行的终端或者是文件结束符EOF,这种情况可能是空值或是'\0'。不对缓冲区做检查可能造成缓冲区泛滥的现象(看下面的实例:BUGS)。
BUGS
Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.
--不要使用gets().因为可能你提前不知道gets()将要读取多少字母,还有gets()会一直存储字母即使在缓冲区结束以后,这个用起来十分危险。这已经损坏了电脑安全。请使用fgets()。
It is not advisable to mix calls to input functions from the stdio library with low-level calls to read(2) for the file descriptor associated with the input stream; the results will be undefined and very probably not what you want.
fgets()
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a new‐
line. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
fgets()最多从流中读取少于字符串长度的字母并使用s指向他们存储在缓冲池中。读取停止遇到Eof或是新的一行。如果新的一行被读,他被存储进缓冲池。在中断符号输入之后, ('\0') 会被自动加到最后一个字母处。
如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。
实际测试效果
fgets函数每次都会把回车键读入,而gets每次使用gcc下都会编译出问题!
额外福利:linux下查看当前程序的缓冲区。stdin和stdout,根据函数名称可以知道前者是输入缓冲区后者是输出缓冲区。两者都是FILE*类型。而在stdio.h文件中可以看到 typedef struct _IO_FILE FILE;其中的_IO_buf_base可以输出他的缓冲区。
struct _IO_FILE {
269 int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
270 #define _IO_file_flags _flags
271
272 /* The following pointers correspond to the C++ streambuf protocol. */
273 /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
274 char* _IO_read_ptr; /* Current read pointer */
275 char* _IO_read_end; /* End of get area. */
276 char* _IO_read_base; /* Start of putback+get area. */
277 char* _IO_write_base; /* Start of put area. */
278 char* _IO_write_ptr; /* Current put pointer. */
279 char* _IO_write_end; /* End of put area. */
280 char* _IO_buf_base; /* Start of reserve area. */
281 char* _IO_buf_end; /* End of reserve area. */
282 /* The following fields are used to support backing up and undo. */
283 char *_IO_save_base; /* Pointer to start of non-current get area. */
284 char *_IO_backup_base; /* Pointer to first valid character of backup area */
285 char *_IO_save_end; /* Pointer to end of non-current get area. */
286
287 struct _IO_marker *_markers;
288
289 struct _IO_FILE *_chain;
291 int _fileno;
292 #if 0
293 int _blksize;
294 #else
295 int _flags2;
296 #endif
297 _IO_off_t _old_offset; /* This used to be _offset but it's too small. */
298
299 #define __HAVE_COLUMN /* temporary */
300 /* 1+column number of pbase(); 0 is unknown. */
301 unsigned short _cur_column;
302 signed char _vtable_offset;
303 char _shortbuf[1];
304
305 /* char* _save_gptr; char* _save_egptr; */
306
307 _IO_lock_t *_lock;
308 #ifdef _IO_USE_OLD_IO_FILE309 };