论坛: 编程破解 标题: C语言:fgets()的问题 复制本贴地址    
作者: kert_t8 [kert_t8]    论坛用户   登录
char *fgets(char *s, int size, FILE *stream);

引用:

      gets()  and fgets() return s on success, and NULL on error or when end of file occurs while no characters have been read.




man是这么说的,当成功的时候就返回s,如果发生错误或者是读到文件尾部并且没有任何字符读入的话就返回NULL

但是在输入的时候要求输入的这个 char *s是分配过内存的。如果是返回NULL,不论什么情况,指针原先所指向的内存地址就丢失了,不能够被free掉,造成内存遗漏,让我很不爽。不知道是不是这样?或者还有什么办法解决?

地主 发表时间: 05-01-30 15:57

回复: kert_t8 [kert_t8]   论坛用户   登录
回复人: kobefly(科比---不惧挑战!) ( ) 信誉:115  2005-1-31 13:19:34  得分: 0 


 
返回NULL是你的函数返回null

s没什么关系的吧

 

Top 

回复人: suyouxin(为什么划船不用浆) ( ) 信誉:100  2005-1-31 13:25:16  得分: 0 


 
fgets 如果失败是不会改变char *s,只是函数返回为NULL

 
回复人: Kert_t8() ( ) 信誉:100  2005-1-31 13:26:36  得分: 0 


 
由于成功的时候就会返回s,所以我一直使用的是
s=fgets(s, size, FileStream);

但是如果照楼上说得那样,我就需要重新声明一个变量,似乎觉得有点不爽。
你们做的程序都是用的: v1=fgets(v2, size, FileStream) 吗?

我没用过c,所以....

 

Top 

回复人: zhousqy() ( ) 信誉:100  2005-1-31 13:30:26  得分: 10 


 
由于成功的时候就会返回s,所以我一直使用的是
s=fgets(s, size, FileStream);

但是如果照楼上说得那样,我就需要重新声明一个变量,似乎觉得有点不爽。
你们做的程序都是用的: v1=fgets(v2, size, FileStream) 吗?

我没用过c,所以....
----------------------------------------
要加判断的。 if (fgets(s、 size、 FileStream) != NULL) { }

 

Top 

回复人: kobefly(科比---不惧挑战!) ( ) 信誉:115  2005-1-31 13:38:14  得分: 10 


 
由于成功的时候就会返回s,所以我一直使用的是
s=fgets(s, size, FileStream);

呵呵
这样是对s重新赋值了吧
函数结束前就一直赋值过了啊

判断的话
楼上说的就对了

 



B1层 发表时间: 05-01-31 14:12

回复: TomyChen [quest]   版主   登录
先给你看一段代码
代码:

/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc.
  This file is part of the GNU C Library.

  The GNU C Library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.

  The GNU C Library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with the GNU C Library; see the file COPYING.LIB.  If not,
  write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */

#include <errno.h>
#include <stdio.h>
#include <string.h>

/* Reads characters from STREAM into S, until either a newline character
  is read, N - 1 characters have been read, or EOF is seen.  Returns
  the newline, unlike gets.  Finishes by appending a null character and
  returning S.  If EOF is seen before any characters have been written
  to S, the function returns NULL without appending the null character.
  If there is a file error, always return NULL.  */
char *
fgets (s, n, stream)
    char *s;
    int n;
    FILE *stream;
{
register char *p = s;

if (!__validfp (stream) || s == NULL || n <= 0)
{
__set_errno (EINVAL);
return NULL;
}

if (ferror (stream))
return NULL;

if (stream->__buffer == NULL && stream->__userbuf)
{
/* Unbuffered stream.  Not much optimization to do.  */
register int c = 0;
while (--n > 0 && (c = getc (stream)) != EOF)
if ((*p++ = c) == '\n')
break;
if (c == EOF && (p == s || ferror (stream)))
return NULL;
*p = '\0';
return s;
}

/* Leave space for the null.  */
--n;

if (n > 0 &&
(!stream->__seen || stream->__buffer == NULL || stream->__pushed_back))
{
/* Do one with getc to allocate a buffer.  */
int c = getc (stream);
if (c == EOF)
return NULL;
*p++ = c;
if (c == '\n')
{
*p = '\0';
return s;
}
else
--n;
}

while (n > 0)
{
size_t i;
char *found;

i = stream->__get_limit - stream->__bufp;
if (i == 0)
{
/* Refill the buffer.  */
int c = __fillbf (stream);
if (c == EOF)
break;
*p++ = c;
--n;
if (c == '\n')
{
*p = '\0';
return s;
}
i = stream->__get_limit - stream->__bufp;
}

if (i > (size_t) n)
i = n;

found = (char *) __memccpy ((void *) p, stream->__bufp, '\n', i);

if (found != NULL)
{
stream->__bufp += found - p;
p = found;
break;
}

stream->__bufp += i;
n -= i;
p += i;
}

if (p == s)
return NULL;

*p = '\0';
return ferror (stream) ? NULL : s;
}

weak_alias (fgets, fgets_unlocked)





[此贴被 TomyChen(quest) 在 01月31日16时33分 编辑过]

B2层 发表时间: 05-01-31 16:32

回复: TomyChen [quest]   版主   登录
再说
很显然,在fgets中,并没有直接的对s进行操作,而所谓的指针地址改变是怎么样才算改变呢。
memcpy(s,"aa",strlen("aa"));//ss > 2
这时候,s并不会改变。而是在
s++;这种情况下才会改变s的原指针。
fgets();显然没这么蠢
在fgets中用了一个*p++;这里移动的并不是s的指针
其实自己做一个简单的例子一试便知,而我也不再班门弄斧了...
而用fgets用的时候常出现的错误通常都是,因为malloc(s)< 文件长度
而在memccpy()(memcpy)。
你还可以试一下
代码:

char *p = (char*) malloc(3);
memcpy(p,"abcd",4);
if(p)
  free(p);


memcpy不会出错,而到free()这才导致异常。

B3层 发表时间: 05-01-31 16:51

回复: TomyChen [quest]   版主   登录
再看看楼上的那些回复,我忍不住想问,是不是fgets()无聊到顶,返回NULL;??

引用:

回复人: Kert_t8() ( ) 信誉:100  2005-1-31 13:26:36  得分: 0 


 
由于成功的时候就会返回s,所以我一直使用的是
s=fgets(s, size, FileStream);

但是如果照楼上说得那样,我就需要重新声明一个变量,似乎觉得有点不爽。
你们做的程序都是用的: v1=fgets(v2, size, FileStream) 吗?

我没用过c,所以....



为什么还要一个*p来接收返回值,直接
代码:

if(NULL == fget(s,n,stream))
return;//这里不用想s肯定是空的
else
printf("%s\n",s);//不用判断也知道s成功取回




典型的脱裤子放屁,所以我觉得他不用c是对的,不然真是侮辱C的灵巧,还有,楼主应该多看看指针相关的文章,源码,比如

str*这类函数原型
mem*这里函数原型
帮助很大


[此贴被 TomyChen(quest) 在 01月31日17时00分 编辑过]

B4层 发表时间: 05-01-31 16:58

回复: kert_t8 [kert_t8]   论坛用户   登录
谢了谢了

不过要说明的是,那个kert_t8是我,我就是kert_t8,我当时是说出我的错误,然后让大家告诉我正确的做法

不过tomychen讲得很仔细,大家都给我说是什么,你讲的是为什么,很好很好
说到了实质性的问题,谢谢

继续努力中

B5层 发表时间: 05-01-31 22:37

回复: zuosi [zuosi]   论坛用户   登录
贴原码:
/*该程序用fgets()显示文本文件的内容,文件的名字由命令行给出*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  FILE *fp;
  char str[128];

  if((fp=fopen(argv[1], "r"))==NULL) {
    printf("Cannot open file.\n");
    exit(1);
  }

  while(!feof(fp)) {
    if(fgets(str, 126, fp)) printf("%s", str);
  }

  fclose(fp);

  return 0;
}
/*用fgets()从控制台读串*/
#include <stdio.h>
#include <string.h>

int main(void)
{
  char str[80];
  int i;

  printf("Enter a string: ");
  fgets(str, 10, stdin);

  /* remove newline, if present */
  i = strlen(str)-1;
  if(str[i]=='\n') str[i] = '\0';/*手工删除新行符*/

  printf("This is your string: %s", str);

  return 0;
}

B6层 发表时间: 05-02-01 18:16

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号