fgets的问题

请勿坑爹 2011-12-31 09:35:56
先贴一段代码 也是论坛里面的问题

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 100
int main(void)
{
char buffer[MAXSIZE];
FILE *fin,*fout;
if((fin = fopen("c:\\file.txt","r")) == NULL){
perror("open fin error\n");
exit(1);
}
if((fout = fopen("c:\\out.txt","w+")) == NULL){
perror("creat outfile error!\n");
exit(1);
}
fgets(buffer,MAXSIZE,fin);
// memset(buffer,0,MAXSIZE);
while(fgets(buffer,MAXSIZE,fin) != NULL){
fputs(buffer,fout);
// memset(buffer,0,MAXSIZE);
}
fclose(fin);
fclose(fout);
remove("c:\\file.txt");
rename("c:\\out.txt","c:\\file.txt");
}


代码就是实现删除打开文件的第一行,这个不是重点
对fgets有一点疑惑,请高手解答
1.如果连续对一个文件读取fgets 如:
fgets(buffer1,MAXSIZE,fin);
fgets(buffer2,MAXSIZE,fin);则会读取文件的第一行 和第二行,好像里面设置了一个什么?为什么第二个直接读的就是第二行?
2 也就是我程序里面注释的问题,我调试了 注释掉memset程序照样可以运行。小弟有点想不通,
如果我第一行是 :i love you
第二行是 :you
采用循环while(fgets(buffer,MAXSIZE,fin) != NULL)那么第一次buffer里面是i love you,我没有疑问,第二次为什么不是
you加上后面的ove you? fgets执行前自动先耍行buffer?还是如果从buffer的首地址写入数据 buffer里面的内容就自动刷新了?
求解答!!
...全文
313 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wesleyluo 2011-12-31
  • 打赏
  • 举报
回复
fgets从一个流中读数据,它希望读到指定长度减一个字符,如果这些字符串中有换行符,它就终止了即使没有读到指定的长度,最后会在读取的字符串为添加一个'\0',这个是重点啦。
赵4老师 2011-12-31
  • 打赏
  • 举报
回复
4楼代码有错,已纠正:
//输出PROG中有但LIST中没有的文本行,即集合PROG-LIST
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#define MAXLINES 1000000
#define MAXCHARS 256
char buf[MAXLINES][MAXCHARS];
char P[256]="PROG";//程序Program需要的文件列表
char L[256]="LIST";//dir /b /s生成的实际文件列表List
FILE *fp,*fl;
int c,n,L1;
int ignore_case=0;
char ln[MAXCHARS];
int icompare(const void *arg1,const void *arg2) {
return stricmp((char *)arg1,(char *)arg2);
}
int compare(const void *arg1,const void *arg2) {
return strcmp((char *)arg1,(char *)arg2);
}
void main(int argc,char **argv) {
if (argc>1) strcpy(P,argv[1]);//命令行参数1覆盖PROG
if (argc>2) strcpy(L,argv[2]);//命令行参数2覆盖LIST
if (argc>3) ignore_case=1;//若存在命令行参数3,忽略大小写
if ((fl=fopen(L,"rt"))==NULL) {
printf("Can not open %s\n",L);
return;
}
if ((fp=fopen(P,"rt"))==NULL) {
fclose(fl);
printf("Can not open %s\n",P);
return;
}
n=0;
while (1) {
if (fgets(ln,MAXCHARS,fl)==NULL) break;//
L1=strlen(ln)-1;
if ('\n'!=ln[L1]) {//超长行忽略后面内容
while (1) {
c=fgetc(fl);
if ('\n'==c || EOF==c) break;//
}
}
while (1) {//去掉行尾的'\n'和空格
if ('\n'==ln[L1] || ' '==ln[L1]) {
ln[L1]=0;
L1--;
if (L1<0) break;//
} else break;//
}
if (L1>=0) {
strcpy(buf[n],ln);
n++;
if (n>=MAXLINES) {
fclose(fl);
fclose(fp);
printf("%s up to %d lines",L,MAXLINES);
return;
}
}
}
fclose(fl);
if (ignore_case) qsort(buf,n,MAXCHARS,icompare);
else qsort(buf,n,MAXCHARS,compare);
while (1) {
if (fgets(ln,MAXCHARS,fp)==NULL) break;//
L1=strlen(ln)-1;
if ('\n'!=ln[L1]) {//超长行忽略后面内容
while (1) {
c=fgetc(fp);
if ('\n'==c || EOF==c) break;//
}
}
while (1) {//去掉行尾的'\n'和空格
if ('\n'==ln[L1] || ' '==ln[L1]) {
ln[L1]=0;
L1--;
if (L1<0) break;//
} else break;//
}
if (L1>=0) {
if (ignore_case) {
if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);
} else {
if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);
}
}
}
fclose(fp);
}
ouyh12345 2011-12-31
  • 打赏
  • 举报
回复
参考fseek
ouyh12345 2011-12-31
  • 打赏
  • 举报
回复
有个文件指针,读或写后,会移动这个指针
赵4老师 2011-12-31
  • 打赏
  • 举报
回复
仅供参考
//输出PROG中有但LIST中没有的文本行,即集合PROG-LIST
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#define MAXLINES 1000000
#define MAXCHARS 256
char buf[MAXLINES][MAXCHARS];
char P[256]="PROG";//程序Program需要的文件列表
char L[256]="LIST";//dir /b /s生成的实际文件列表List
FILE *fp,*fl;
int c,n,L1;
int ignore_case=0;
char ln[MAXCHARS];
int icompare(const void *arg1,const void *arg2) {
return stricmp((char *)arg1,(char *)arg2);
}
int compare(const void *arg1,const void *arg2) {
return strcmp((char *)arg1,(char *)arg2);
}
void main(int argc,char **argv) {
if (argc>1) strcpy(P,argv[1]);//命令行参数1覆盖PROG
if (argc>2) strcpy(L,argv[2]);//命令行参数2覆盖LIST
if (argc>3) ignore_case=1;//若存在命令行参数3,忽略大小写
if ((fl=fopen(L,"rt"))==NULL) {
printf("Can not open %s\n",L);
return;
}
if ((fp=fopen(P,"rt"))==NULL) {
fclose(fl);
printf("Can not open %s\n",P);
return;
}
n=0;
while (1) {
if (fgets(ln,MAXCHARS,fl)==NULL) break;//
L1=strlen(ln)-1;
if ('\n'!=ln[L1]) {//超长行忽略后面内容
while (1) {
c=fgetc(fl);
if ('\n'==c || EOF==c) break;//
}
}
while (1) {//去掉行尾的空格
if (' '==ln[L1]) {
ln[L1]=0;
if (0==L1) break;//
L1--;
} else break;//
}
if (L1>0) {
strcpy(buf[n],ln);
n++;
if (n>=MAXLINES) {
fclose(fl);
fclose(fp);
printf("%s up to %d lines",L,MAXLINES);
return;
}
}
}
fclose(fl);
if (ignore_case) qsort(buf,n,MAXCHARS,icompare);
else qsort(buf,n,MAXCHARS,compare);
while (1) {
if (fgets(ln,MAXCHARS,fp)==NULL) break;//
L1=strlen(ln)-1;
if ('\n'!=ln[L1]) {//超长行忽略后面内容
while (1) {
c=fgetc(fl);
if ('\n'==c || EOF==c) break;//
}
}
while (1) {//去掉行尾的空格
if (' '==ln[L1]) {
ln[L1]=0;
if (0==L1) break;//
L1--;
} else break;//
}
if (L1>0) {
if (ignore_case) {
if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);
} else {
if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);
}
}
}
fclose(fp);
}
赵4老师 2011-12-31
  • 打赏
  • 举报
回复
查MSDN是Windows程序员必须掌握的技能之一。

fgets, fgetws
Get a string from a stream.

char *fgets( char *string, int n, FILE *stream );

wchar_t *fgetws( wchar_t *string, int n, FILE *stream );

Function Required Header Compatibility
fgets <stdio.h> ANSI, Win 95, Win NT
fgetws <stdio.h> or <wchar.h> ANSI, Win 95, Win NT


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version


Return Value

Each of these functions returns string. NULL is returned to indicate an error or an end-of-file condition. Use feof or ferror to determine whether an error occurred.

Parameters

string

Storage location for data

n

Maximum number of characters to read

stream

Pointer to FILE structure

Remarks

The fgets function reads a string from the input stream argument and stores it in string. fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first. The result stored in string is appended with a null character. The newline character, if read, is included in the string.

fgets is similar to the gets function; however, gets replaces the newline character with NULL. fgetws is a wide-character version of fgets.

fgetws reads the wide-character argument string as a multibyte-character string or a wide-character string according to whether stream is opened in text mode or binary mode, respectively. For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.

Generic-Text Routine Mappings

TCHAR.H Routine _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined
_fgetts fgets fgets fgetws


Example

/* FGETS.C: This program uses fgets to display
* a line from a file on the screen.
*/

#include <stdio.h>

void main( void )
{
FILE *stream;
char line[100];

if( (stream = fopen( "fgets.c", "r" )) != NULL )
{
if( fgets( line, 100, stream ) == NULL)
printf( "fgets error\n" );
else
printf( "%s", line);
fclose( stream );
}
}


Output

/* FGETS.C: This program uses fgets to display



Stream I/O Routines

See Also fputs, gets, puts
面包大师 2011-12-31
  • 打赏
  • 举报
回复
会打印到行结束符\r\n就停止了,读取也是
IVERS0N 2011-12-31
  • 打赏
  • 举报
回复
行结束符\r\n
赵4老师 2011-12-31
  • 打赏
  • 举报
回复
The fgets function reads a string from the input stream argument and stores it in string. fgets reads characters from the current stream position to and including the first newline character, to the end of the stream, or until the number of characters read is equal to n – 1, whichever comes first. The result stored in string is appended with a null character. The newline character, if read, is included in the string.

fgets is similar to the gets function; however, gets replaces the newline character with NULL. fgetws is a wide-character version of fgets.
仰望星空 2011-12-31
  • 打赏
  • 举报
回复
1. 解决问题1我们先从问题2入手;
2. 清楚fgets()、fgets()函数的运行机制。

#define MAXSIZE 100
以fgets(buffer,MAXSIZE,fin),fgets(buffer,fout)为例。
fgets()函数,fin记录字符开始读取的位置;读取到第一个换行符后,或者读取MAXSIZE-1个字符,或者读取到文件结尾;然后fgets()函数向末尾添加'\0'形成一个字符串,而buffer则是这个字符串的地址;fin这时记录的是文件中还没有访问的第一个字符(按顺序)的位置,可以理解为每次读取一个字符,fin做一次++运算。
fputs()函数将buffer指向的字符串写入到fout指向的文件。

如果file.txt的内容如下:
I love you //第一行内容;
you //第二行内容;
...... //第n行内容;
在楼主的例子中,进入while循环后,第一次调用fgets函数,fin指向‘I'的位置,从I开始读取字符到buffer指向的字符串,我们希望能够一次读取MAXSIZE个字符,但读取到10个字符以后就遇到换行'\n',本次读取在读取完'\n'后提前结束,并在末尾加一个'\0'表明字符串结束;fin 指向未访问的下一个字符,即第二行的首字符'y'。buffer被传递给fputs(),遇到‘\0’结束,本次输出显示"I love you"。
同理,第二次调用fgets(),"you\0"被存入buffer指向的字符串中,fput()输出遇到'\0'结束,所以只能是"you"而不会是"youove you"。



Ever_lover 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wesleyluo 的回复:]

fgets从一个流中读数据,它希望读到指定长度减一个字符,如果这些字符串中有换行符,它就终止了即使没有读到指定的长度,最后会在读取的字符串为添加一个'\0',这个是重点啦。
[/Quote]+1
hxf0722 2011-12-31
  • 打赏
  • 举报
回复
建议去看一下fgets的使用介绍,man 一下也可以

69,378

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧