fgets(string,int,fp)
回车读入测试
1 #include <stdio.h> 2 int main() 3 { 4 FILE *fp; 5 char ch1[12],ch2[12],ch3[12],ch4[13]; 6 fp=fopen("case1.in","r"); 7 fgets(ch1,10,fp); 8 fseek(fp,0,0); 9 fgets(ch2,11,fp); 10 fseek(fp,0,0); 11 fgets(ch3,12,fp); 12 fseek(fp,0,0); 13 fgets(ch4,13,fp); 14 fseek(fp,0,0); 15 printf("10:%s;\n",ch1); 16 printf("11:%s;\n",ch2); 17 printf("12:%s;\n",ch3); 18 printf("13:%s;\n",ch4); 19 fclose(fp); 20 return 0; 21 }
case1.in内容:
ottffssent
abcdefghij
kl
运行结果:
10:ottffssen;
11:ottffssent;
12:ottffssent
;
13:ottffssent
;
结论:
字符串要留空位给'\0',如果有回车的话要再预留空位给回车'13',即字符数量为10的字符串则用fgets时要取n=12
如果fgets中n的数量过少而读不入回车,会导致输出时没有换行
如果fgets中n的数量过多,那么回车已经停止了读入字符了,即回车符后紧跟'\0'
空格读入测试
代码同上
case1.in有修改:
ottff sent
abcde ghij
kl
运行结果:
10:ottff sen;
11:ottff sent;
12:ottff sent
;
13:ottff sent
;
结论:
空格被视为普通字符处理,不能中止字符的读入.而回车可以
代码增加一点
1 fscanf(fp,"%s",ch5); 2 fscanf(fp,"%s",ch6); 3 fscanf(fp,"%s",ch7); 4 fscanf(fp,"%s",ch8); 5 printf("fscanf1:%s;\n",ch5); 6 printf("fscanf2:%s;\n",ch6); 7 printf("fscanf3:%s;\n",ch7); 8 printf("fscanf4:%s;\n",ch8);
case1.in有修改:
ottff sent
abcde,ghij
kl
运行结果:
fscanf1:ottff;
fscanf2:sent;
fscanf3:abcde;
fscanf4:ghij;
结论:fscanf中,空格,回车,标点符号都可以中止输入
FILE指针中的当前位置
//--------------------------------------------------------------------------------------------
FILE 是 I/O 系统用的。不同编译器结构不完全相同。
char* _ptr;    文件指针当前位置,缓冲区内 马上读和写的位置。
 int _cnt;  缓冲区内 现有可以读的字符个数
char* _base;  缓冲区
int _flag; 文件流 特征标志,例如:只读,只写,读写,错误,文件结束,2进制文件。
int _file;  系统里文件属性,例如:谁可以读写(用户自己,用户组,管理员)。
int _charbuf; -- 供 ungetc() 使用的缓冲存储单元。
int _bufsiz;  已分配的缓冲区的大小。
char* _tmpfname; 临时文件名
//--------------------------------------------------------------------------------------------
typedef struct{
short		level;		缓冲区使用量
unsigned	flags;		文件状态标志
char		fd;		文件描述符
short		bsize;		缓冲区大小
unsigned char	*buffer;	文件缓冲区首地址
unsigned char	*curp;		指向文件缓冲区的工作指针
unsigned char 	hold;		其他信息
unsigned	istemp;
short		token;
}FILE;
//--------------------------------------------------------------------------------------------
struct __sFILE64 {
#  if !defined _AEABI_PORTABILITY_LEVEL || _AEABI_PORTABILITY_LEVEL == 0
  unsigned char *_p;	/* current position in (some) buffer */
  int	_r;		/* read space left for getc() */
  int	_w;		/* write space left for putc() */
  short	_flags;		/* flags, below; this FILE is free if 0 */
  short	_file;		/* fileno, if Unix descriptor, else -1 */
  struct __sbuf _bf;	/* the buffer (at least 1 byte, if !NULL) */
  int	_lbfsize;	/* 0 or -_bf._size, for inline putc */
struct _reent *_data;
  /* operations */
  _PTR	_cookie;	/* cookie passed to io functions */
  _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *, _PTR,
					   char *, int));
  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR,
					    const char *, int));
  _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int));
  int _EXFUN((*_close),(struct _reent *, _PTR));
  /* separate buffer for long sequences of ungetc() */
  struct __sbuf _ub;	/* ungetc buffer */
  unsigned char *_up;	/* saved _p when _p is doing ungetc data */
  int	_ur;		/* saved _r when _r is counting ungetc data */
  /* tricks to meet minimum requirements even when malloc() fails */
  unsigned char _ubuf[3];	/* guarantee an ungetc() buffer */
  unsigned char _nbuf[1];	/* guarantee a getc() buffer */
  /* separate buffer for fgetline() when line crosses buffer boundary */
  struct __sbuf _lb;	/* buffer for fgetline() */
  /* Unix stdio files get aligned to block boundaries on fseek() */
  int	_blksize;	/* stat.st_blksize (may be != _bf._size) */
  int   _flags2;        /* for future use */
  _off64_t _offset;     /* current lseek offset */
  _fpos64_t _EXFUN((*_seek64),(struct _reent *, _PTR, _fpos64_t, int));
#   ifndef __SINGLE_THREAD__
  _flock_t _lock;	/* for thread-safety locking */
#   endif
#  endif /* _AEABI_PORTABILITY_LEVEL */
  _mbstate_t _mbstate;	/* for wide char stdio functions. */
};
//--------------------------------------------------------------------------------------------
不同的编译器有不同的stdio.h,也对应着定义的不同
codeblocks使用第一种定义,当前指针为fp->_ptr
学校教材上使用第二种,当前指针为fp->curp
学校oj系统用第三种定义,编译器G++,当前指针为fp->_p
然而cb上和学校oj系统上的当前指针有点不同
执行ch=fgetc(fp)是ch读入fp->_ptr指向的内容,然后指针自动前进一位
即case1.in中有:abcd
第一步执行ch=fgetc(fp)后,ch='a',而fp->_ptr已经指向b了,*(fp->_ptr)=b
但在学校oj系统上,ch=fgetc(fp)是指针前进一位,然后读入内容到ch
即case1.in中:abcd,执行ch=fgetc(fp)后,ch='a',此时fp->_p还是在a上,再执行ch=fgetc(fp),fp->_p移动到b,ch=b
这时*(fp->_p)=b,*(fp->_p+1)=c,
换做cb上这样执行两次ch=fgetc(fp)后,*(fp->_ptr)=c了
按照教材上的说法,教材的指针原理和cb上的相同..
妈蛋..学校那题错了6次才猜出来是这个原因,测试后pase.
 
                    
                     
                    
                 
                    
                 
 posted on
 posted on 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号