user-0 提问: 求一个gets（）函数的内部代码

回复:
user: user-1
content: C程序设计语言，是C父写的，不是谭浩强写的 里有源码，gets 就是 fgets 指定 stdin参数版本 7.7.	行输入和行输出  标准库提供了一个输入函数 fgets，它和前面几章中用到的函数 getline 类似。  char *fgets(char *line, int maxline, FILE *fp) fgets 函数从 fp 指向的文件中读取下一个输入行(包括换行符)，并将它存放在字符数组  况下，fgets 返回 line，但如果遇到了文件结尾或发生了错误，则返回 NULL(我们编写的 getline 函数返回行的长度，这个值更有用，当它为 0 时意味着已经到达了文件的结尾)。 输出函数 fputs 将一个字符串(不需要包含换行符)写入到一个文件中:  int fputs(char *line, FILE *fp) 如果发生错误，该函数将返回 EOF，否则返回一个非负值。  　　库函数 gets和 puts的功能与 fgets和 fputs函数类似，但它们是对 stdin和 stdout 进行操作。有一点我们需要注意，gets 函数在读取字符串时将删除结尾的换行符('\n')， 而 puts 函数在写入字符串时将在结尾添加一个换行符。  　　下面的代码是标准库中 fgets 和 fputs 函数的代码，从中可以看出，这两个函数并没 有什么特别的地方。代码如下所示:  /* fgets:	get at most n chars from iop */ char *fgets(char *s, int n, FILE *iop) { register int c; register char *cs;  cs = s; while (--n > 0 && (c = getc(iop)) != EOF) if ((*cs++ = c) == '\n') break; *cs = '\0'; return (c == EOF && cs == s) - NULL : s; }  /* fputs:	put string s on file iop */ int fputs(char *s, FILE *iop) { int c;  while (c = *s++) putc(c, iop); return ferror(iop) - EOF : 0; }  　　ANSI 标准规定，ferror 在发生错误时返回非 0 值，而 fputs 在发生错误时返回 EOF， 其它情况返回一个非负值。  使用 fgets 函数很容易实现 getline 函数:  /* getline:	read a line, return length */ int getline(char *line, int max) { if (fgets(line, max, stdin) == NULL) return 0; else return strlen(line); }

user: user-2
content: C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\gets.c /*** *gets.c - read a line from stdin * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       defines gets() and getws() - read a line from stdin into buffer * *******************************************************************************/  #include <cruntime.h> #include <stdio.h> #include <dbgint.h> #include <file2.h> #include <internal.h> #include <internal_securecrt.h> #include <mtdll.h> #include <tchar.h> #include <limits.h>  #ifdef _UNICODE #define _getchar_helper _getwchar_nolock #else  /* _UNICODE */ #define _getchar_helper _getchar_nolock #endif  /* _UNICODE */  _TCHAR * __cdecl _getts_helper (     _TCHAR *string,     size_t bufferSize,     int earlyOutIfEOFIsFirstChar ) {     int ch = 0;     _TCHAR *pointer = string;     _TCHAR *retval = string;      _VALIDATE_RETURN( (string != NULL), EINVAL, NULL);     _VALIDATE_RETURN( (bufferSize > 0), EINVAL, NULL);      /* The C Standard states the input buffer should remain     unchanged if EOF is encountered immediately. Hence we     do not blank out the input buffer here */      _lock_str2(0, stdin);     __try { #ifndef _UNICODE         _VALIDATE_STREAM_ANSI_SETRET(stdin, EINVAL, retval, NULL);         if (retval == NULL)         {             goto done;         } #endif  /* _UNICODE */          /* special case: check if the first char is EOF and treat it differently if the user requested so */         ch = _getchar_helper();         if (ch == _TEOF)         {             retval = NULL;             if (earlyOutIfEOFIsFirstChar)                 goto done;         }          if (bufferSize == (size_t)-1)         {             /* insecure case: no buffer size check, no debug filling */             while (ch != _T('\n') && ch != _TEOF)             {                 *pointer++ = (_TCHAR)ch;                 ch = _getchar_helper();             }             *pointer = 0;         }         else         {             /* secure case, check buffer size; if buffer overflow, keep on reading until /n or EOF */             size_t available = bufferSize;             while (ch != _T('\n') && ch != _TEOF)             {                 if (available > 0)                 {                     --available;                     *pointer++ = (_TCHAR)ch;                 }                 ch = _getchar_helper();             }             if (available == 0)             {                 _RESET_STRING(string, bufferSize);                 _RETURN_BUFFER_TOO_SMALL_ERROR(string, bufferSize, NULL);             }             *pointer = 0;             _FILL_STRING(string, bufferSize, bufferSize - available + 1);         }          /* Common return */ done: ;      }     __finally     {         _unlock_str2(0, stdin);     }      return retval; }  /*** *errno_t gets_s(string, sz) - read a line from stdin * *Purpose: * * *Entry: *       char *string      - place to store read string. *       size_t bufferSize - length of dest buffer * *Exit: *       returns string, filled in with the line of input *       null string if \n found immediately or if EOF found immediately *Exceptions: * *******************************************************************************/  _TCHAR * __cdecl _getts_s (     _TCHAR *string,     size_t bufferSize ) {     return _getts_helper(string, bufferSize, 0 /* treat first EOF as \n */); }  /*** *char *gets(string) - read a line from stdin * *Purpose: *       Gets a string from stdin terminated by '\n' or EOF; don't include '\n'; *       append '\0'. * *Entry: *       char *string - place to store read string, assumes enough room. * *Exit: *       returns string, filled in with the line of input *       null string if \n found immediately *       NULL if EOF found immediately * *Exceptions: * *******************************************************************************/  _TCHAR * __cdecl _getts (     _TCHAR *string ) {     return _getts_helper(string, (size_t)-1, 1 /* early out if EOF is first char read */); }

user: user-3
content: 很早之前已经有人讨论过 https://bbs.csdn.net/topics/100041558