fgets()的问题

Ashnu 2004-05-05 08:23:08
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #define MAXLINE 82
6 main()
7 {
8 char buff[82];
9 char usrname[12]="0", passwd[24]="0";
10 int fd=open("tmpfile", O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
11 printf("username: ");
12 scanf("%12s", usrname);
13 printf("password: ");
14 scanf("%24s", passwd);
15 printf("Subject: ");
16 if (fgets(buff, MAXLINE, stdin)==NULL)
17 {
18 perror("fgets");
19 exit(1);
20 }
21 if (buff[79] != '\n') buff[80]='\n';
22 printf("buff: %s\n", buff);
23 write(fd, "Subject: ", strlen("Subject: "));
24 write(fd, buff, strlen(buff));
25 printf("Content:\n");
26 while (fgets(buff, MAXLINE, stdin) != NULL)
27 write(fd, buff, strlen(buff));
28 close(fd);
29 }

代码如上.问题是,为什么第16行的fgets()没有起作用呢?应该怎么解决?

PS: 标准I/O库要想搞明白还真是不容易.每次都在它上面吃亏.这次恐怕又是缓存惹的祸 :(
...全文
1539 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ashnu 2004-05-06
  • 打赏
  • 举报
回复
但问题还是没有解决.我在第14行后加上了一句"fflush(stdin);",但是第16行的fgets仍然没有起作用啊
mobihigh 2004-05-06
  • 打赏
  • 举报
回复
看到你的执行程序为a.out,就知道你还没有养成好的习惯,故忠告一声!
mobihigh 2004-05-06
  • 打赏
  • 举报
回复
问题就在于fgets(buff, MAXLINE, stdin)==NULL中的==NULL判断依据
有问题。从stdin读取数据正常情况下返回值是不可能为NULL。
因此while (fgets(buff, MAXLINE, stdin) != NULL)就会进入死循环。
另外在输入password后,必然以回车作为结束。这样紧接着调用fgets的结果是buff="\n"。参照msdn的fgets说明可以看到fgets并不会将'\n'转成NULL的。运行的结果当然就会与你的期望不同了。
icelover 2004-05-06
  • 打赏
  • 举报
回复
因为当fgets前面的一句输入密码scanf("%24s",password)后,没有清空缓冲区,因此fgets读入的仍是上次输入留在缓冲区的东西
因此应在后面加上一句fflush(stdin)
Ashnu 2004-05-06
  • 打赏
  • 举报
回复
恕我愚昧,但这和makefile有关系吗? :)
saoyu 2004-05-06
  • 打赏
  • 举报
回复
清空缓冲
mobihigh 2004-05-06
  • 打赏
  • 举报
回复
你在linux下编程为什么不使用makefile?学习在unix平台下编程书写
makefile(工程维护文件,相当于vc中的.dsp文件)十分重要。对
学习使用vc也十分有意义。
Ashnu 2004-05-06
  • 打赏
  • 举报
回复
回mobihigh(mobihigh):
那可真是奇怪啊,我把我的程序和你上面给的绝对仔细的比较了一下,除了#include <io.h> //modify和nt fd=open("tmpfile", O_WRONLY|O_APPEND|O_CREAT|O_TRUNC);//modify, S_IRUSR|S_IWUSR);这两行不同外,没有区别,而且绝对重新编译了啊.结果仍然不对.hehe,真是很奇怪啊

回yi2001(yi2001):
我现在暂时就是这么解决的啊,不过效率太差啊 :(
yi2001 2004-05-06
  • 打赏
  • 举报
回复
在16行之前加上一句:
while(getchar()!='\n') continue;
mobihigh 2004-05-06
  • 打赏
  • 举报
回复
不会吧,我在vc下测试的,对于c语言而言,linux平台与
windows平台结果也应该一致。不信你可以在windows下试试。
希望你确认linux下的程序是否重新编译生成新的执行程序。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h> //modify
#define MAXLINE 82
main()
{
char buff[82];
char usrname[12]="0", passwd[24]="0";
int fd=open("tmpfile", O_WRONLY|O_APPEND|O_CREAT|O_TRUNC);//modify, S_IRUSR|S_IWUSR);
printf("username: ");
scanf("%12s", usrname);
printf("password: ");
scanf("%24s", passwd);
fflush(stdin);//modify
printf("Subject: ");
if (fgets(buff, MAXLINE, stdin)==NULL)
{
perror("fgets");
exit(1);
}
if (buff[79] != '\n') buff[80]='\n';
printf("buff: %s\n", buff);
write(fd, "Subject: ", strlen("Subject: "));
write(fd, buff, strlen(buff));
printf("Content:\n");
while (fgets(buff, MAXLINE, stdin) != NULL)
write(fd, buff, strlen(buff));
close(fd);
}
Ashnu 2004-05-06
  • 打赏
  • 举报
回复
hehe, 我也试过了啊,加上"fflush(stdin);"后第16行的fgets仍然没有停下来等待输入啊.我的系统是linux.下面是我的输出:

[leona@Ash leona]$ ./a.out
username: hello
password: world
Subject: buff:

Content:

Subject后面应该会停下来等待输入的,但是它直接打印出了"buff:"
mobihigh 2004-05-06
  • 打赏
  • 举报
回复
肯定可以的,我试过了。
可能你的问题是发现tmpfile文件内容没有改变,原因应该在于打开文件的
方式有误,导致文件内容没有变更,保持上一次的结果。
cngdzhang 2004-05-05
  • 打赏
  • 举报
回复
fflush(stdin)

标准输入缓冲清空(丢弃)

别的情况似乎还没有遇到过
Ashnu 2004-05-05
  • 打赏
  • 举报
回复
还有,为什么说,对fgets,错误是当传入s为NULL的时候才会遇到,难道不会有别的错误情况吗?
Ashnu 2004-05-05
  • 打赏
  • 举报
回复
fflush的效果是什么样的?假设我fflush(stdin),那么标准输入缓冲中现存内容会如何处理?直接丢弃还是怎么的?
cngdzhang 2004-05-05
  • 打赏
  • 举报
回复
刷新缓冲用
fflush

flushall
cngdzhang 2004-05-05
  • 打赏
  • 举报
回复
看一下fgets的说明

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

On success,
fgets returns the string pointed to by s.
On end-of-file or error, fgets returns null.

操作成功时返回的是s的值

如果碰到文件结束或错误的时候,fgets返回 NULL
因为输入的过程中一般只会按下回车,很少会是EOF的,所以不会是碰到文件结束
而错误是当你传入s是NULL的时候才会遇到

所以基本上是不可能返回NULL的
而且输入超过了长度n的时候,fgets会自动截断的,属于操作成功
Ashnu 2004-05-05
  • 打赏
  • 举报
回复
回junnyfeng(听风):

我想也是这个缓冲的问题.但怎么才能清空现有缓存内容呢?
Ashnu 2004-05-05
  • 打赏
  • 举报
回复
问题是,它根本就没有停下来让我输入任何东西,而是直接往下执行,直到26行才停下接受输入
junnyfeng 2004-05-05
  • 打赏
  • 举报
回复
当你输入的passwd超过24个时就看到效果了
加载更多回复(3)

69,371

社区成员

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

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