user-0 提问: 菜鸟求助！文件指针和文件内部指针的区别

回复:
user: user-1
content: /***       *FILE   *_openfile(filename,   mode,   shflag,   stream)   -   open   a   file   with   string       *               mode   and   file   sharing   flag.       *       *Purpose:       *               parse   the   string,   looking   for   exactly   one   of   {rwa},   at   most   one   '+',       *               at   most   one   of   {tb},   at   most   one   of   {cn},   at   most   one   of   {SR},   at   most       *               one   'T',   and   at   most   one   'D'.   pass   the   result   on   as   an   int   containing       *               flags   of   what   was   found.   open   a   file   with   proper   mode   if   permissions       *               allow.   buffer   not   allocated   until   first   i/o   call   is   issued.   intended       *               for   use   inside   library   only       *       *Entry:       *               char   *filename   -   file   to   open       *               char   *mode   -   mode   to   use   (see   above)       *               int   shflag   -   file   sharing   flag       *               FILE   *stream   -   stream   to   use   for   file       *       *Exit:       *               set   stream's   fields,   and   causes   system   file   management   by   system   calls       *               returns   stream   or   NULL   if   fails       *       *Exceptions:       *       *******************************************************************************/  FILE   *   __cdecl   _openfile   (                       const   char   *filename,                       REG3   const   char   *mode,                       int   shflag,                       FILE   *str                       )       {                       REG2   int   modeflag;                       int   streamflag   =   _commode;                       int   commodeset   =   0;                       int   whileflag;                       int   filedes;                       REG1   FILE   *stream;                             _ASSERTE(filename   !=   NULL);                       _ASSERTE(mode   !=   NULL);                       _ASSERTE(str   !=   NULL);                             /*   Parse   the   user's   specification   string   as   set   flags   in                                     (1)   modeflag   -   system   call   flags   word                                     (2)   streamflag   -   stream   handle   flags   word.   */                             /*   First   mode   character   must   be   'r',   'w',   or   'a'.   */                             switch   (*mode)   {                       case   'r':                                       modeflag   =   _O_RDONLY;                                       streamflag    ¦=   _IOREAD;                                       break;                       case   'w':                                       modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_TRUNC;                                       streamflag    ¦=   _IOWRT;                                       break;                       case   'a':                                       modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_APPEND;                                       streamflag    ¦=   _IOWRT;                                       break;                       default:                                       return(NULL);                                       break;                       }                             /*   There   can   be   up   to   three   more   optional   mode   characters:                             (1)   A   single   '+'   character,                             (2)   One   of   't'   and   'b'   and                             (3)   One   of   'c'   and   'n'.                       */                             whileflag=1;                             while(*++mode   &&   whileflag)                                       switch(*mode)   {                                             case   '+':                                                       if   (modeflag   &   _O_RDWR)                                                                       whileflag=0;                                                       else   {                                                                       modeflag    ¦=   _O_RDWR;                                                                       modeflag   &=   ~(_O_RDONLY    ¦   _O_WRONLY);                                                                       streamflag    ¦=   _IORW;                                                                       streamflag   &=   ~(_IOREAD    ¦   _IOWRT);                                                       }                                                       break;                                       case   't':                                                       if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))                                                                       whileflag=0;                                                       else                                                                       modeflag    ¦=   _O_TEXT;                                                       break;                                             case   'b':                                                       if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))                                                                       whileflag=0;                                                       else                                                                       modeflag    ¦=   _O_BINARY;                                                       break;                                       case   'c':                                                       if   (commodeset)                                                                       whileflag=0;                                                       else   {                                                                       commodeset   =   1;                                                                       streamflag    ¦=   _IOCOMMIT;                                                       }                                                       break;                                             case   'n':                                                       if   (commodeset)                                                                       whileflag=0;                                                       else   {                                                                       commodeset   =   1;                                                                       streamflag   &=   ~_IOCOMMIT;                                                       }                                                       break;                                       default:                                                       whileflag=0;                                                       break;                                       }                             /*   Try   to   open   the   file.     Note   that   if   neither   't'   nor   'b'   is                             specified,   _sopen   will   use   the   default.   */                             if   ((filedes   =   _sopen(filename,   modeflag,   shflag,   CMASK))    <   0)                                       return(NULL);                             /*   Set   up   the   stream   data   base.   */             #ifndef   CRTDLL                       /*   force   library   pre-termination   procedure   */                       _cflush++;       #endif     /*   CRTDLL   */                             /*   Init   pointers   */                       stream   =   str;                             stream->_flag   =   streamflag;                       stream->_cnt   =   0;                       stream->_tmpfname   =   stream->_base   =   stream->_ptr   =   NULL;                       stream->_file   =   filedes;                             return(stream);       }

user: user-1
content: 引用 7 楼 su_787910081 的回复:[quote=引用 5 楼 shenchenman 的回复:] 文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 真心有点扯 [/quote]  搞笑 请问哪里扯？   Return Value    --------------------------------------------------------------------------------      Each of these functions returns a pointer to the open file. A null pointer value indicates an error. If filename or mode is NULL or an empty string, these functions trigger the invalid parameter handler, which is described in Parameter Validation. If execution is allowed to continue, these functions return NULL and set errno to EINVAL. 返回一个FILE*，也就是文件指针，指向一个文件，你要是做偏移了，能close掉？  文件内部指针，本身对调用fopen的人来说不可见的，CFILE类内部管理的一个指针变量，读取内容时，会做处理。什么叫扯？求解释 另附一个CFILE重载函数的实现： /***       *FILE   *_fsopen(file,   mode,   shflag)   -   open   a   file       *       *Purpose:       *               Opens   the   file   specified   as   a   stream.     mode   determines   file   mode:       *               "r":   read               "w":   write             "a":   append       *               "r+":   read/write                                 "w+":   open   empty   for   read/write       *               "a+":   read/append       *               Append   "t"   or   "b"   for   text   and   binary   mode.   shflag   determines   the       *               sharing   mode.   Values   are   the   same   as   for   sopen().       *       *Entry:       *               char   *file   -   file   name   to   open       *               char   *mode   -   mode   of   file   access       *       *Exit:       *               returns   pointer   to   stream       *               returns   NULL   if   fails       *       *Exceptions:       *       *******************************************************************************/             FILE   *   __cdecl   _tfsopen   (                       const   _TSCHAR   *file,                       const   _TSCHAR   *mode                       ,int   shflag                       )       {                       REG1   FILE   *stream;                       REG2   FILE   *retval;                             _ASSERTE(file   !=   NULL);                       _ASSERTE(*file   !=   _T('/0'));                       _ASSERTE(mode   !=   NULL);                       _ASSERTE(*mode   !=   _T('/0'));                             /*   Get   a   free   stream   */                       /*   [NOTE:   _getstream()   returns   a   locked   stream.]   */                             if   ((stream   =   _getstream())   ==   NULL)                                       return(NULL);                             /*   open   the   stream   */       #ifdef   _UNICODE                       retval   =   _wopenfile(file,mode,shflag,stream);       #else     /*   _UNICODE   */                       retval   =   _openfile(file,mode,shflag,stream);       #endif     /*   _UNICODE   */                             /*   unlock   stream   and   return.   */                       _unlock_str(stream);                       return(retval);       }

user: user-2
content: FILE 是C流，是一种带缓冲的，表示文件的数据结构。 FILE* fp 是流指针，是C，C++语言的指针概念中的指针，指向的数据类型是FILE。  内部指针，是文件读写的当前位置指针，其实就是个位置； 文件读写的当前位置，不是C，C++语言的指针。  流数据结构中有一个域，表示这个当前位置。 所以，可以通过流指针，改变文件读写的当前位置。  fseek就是专门做这个的，fwrite,fread 也会改变它，，， 另外，fgetc,fgets,fputc,fputs,fscanf,fprintf 也会改变它 ftell 可以获取这个当前位置。

user: user-3
content: 引用 5 楼 shenchenman 的回复:文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 真心有点扯

user: user-4
content: 引用 5 楼 shenchenman 的回复:文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容 扯

user: user-1
content: 文件指针指向文件，自增没有意义； 内部指针指向文件的数据，对其自增就能不断读文件内容

user: user-4
content: FILE *是地址 ftell()的返回值是代表文件字节偏移量的一个数。

user: user-5
content: fp没有移动。  你要操作一个文件就用文字指针指向这个文件。实际上文件指针指向的是一个数据结构，这个数据结构中有各种成员用来管理这个打开的文件。而文件内部指针只是这些成员中的一个，用来管理文件偏移量。还有管理读写模式之类的成员等等。

user: user-6
content: 两者的区别在于 fp说白了标识你要操作哪个文件，所谓的‘文件指针’ 另一个文件内部指针是说你对这个文件的操作位置 比如fopen打开后，你fread是从该文件开头读起 但是你调用fseek后fread，就能从该文件的特定位置读数据，就是所谓的‘文件内部指针’