提问人:ECH 提问时间:12/5/2022 更新时间:12/5/2022 访问量:89
While 循环不能不以 eof 终止
While loop cannot be not terminated with eof
问:
char buf_in()
{
if(read_pos==16)
{
read_pos=0;
read(fd_in,buffer_in,16);
}
return buffer_in[read_pos++];
}
void buf_out(char data)
{
if(write_pos==16)
{
write_pos=0;
write(fd_out,buffer_out,16);
}
buffer_out[write_pos++]=data;
}
int main()
{
fd_in=open("input.txt",O_RDONLY);
fd_out=open("result.txt",O_WRONLY|O_CREAT,0666);
char ch;
while((ch=buf_in())!= EOF)
{
buf_out(ch);
}
close(fd_in);
close(fd_out);
return 0;
}
这些是我的代码,当我查看结果 .txt 时,它看起来像输入文件的内容和一堆空值,输入文件的内容再次出现。所以它永远不会结束。我的代码有什么问题?谢谢。
答:
1赞
Andreas Wenzel
12/5/2022
#1
如果要工作,则必须对函数进行编程,使其在由于到达文件末尾而导致读取失败时返回。但是,您没有这样做。相反,您忽略了 的返回值,因此您不会注意到何时到达文件末尾。while((ch=buf_in())!= EOF)
buf_in
EOF
read
此外,a 不保证能够表示值 。如果要确保数据类型可以表示值,请改用。char
EOF
int
EOF
您似乎认为这是出现在文件末尾的字符的字符代码。然而,事实并非如此。该值不是字符代码。它是由 getchar
等函数返回的特殊值,用于指示未检索到任何字符。该函数不一定返回值以指示 end-or-file 或错误。它使用不同的机制来报告此问题。它将返回成功读取或出错的字节数。该值可能等于某些平台上的值,但您不能依赖此值。EOF
EOF
read
EOF
-1
EOF
-1
为了解决上述问题,您可以像这样重写函数:buf_in
int buf_in( void )
{
if ( read_pos == 16 )
{
read_pos = 0;
if ( read( fd_in, buffer_in, 16 ) == -1 )
return EOF;
}
return (unsigned char)buffer_in[read_pos++];
}
强制转换为是必需的,以便保证所有字符代码都可与值区分开来。unsigned char
EOF
但是,这不能正确处理仅在 和 字节之间读取而不是字节的情况。read
1
15
16
因此,最好添加一个附加变量并将此变量初始化为 。之后,您可以使用以下代码:ssize_t bytes_read
0
int buf_in( void )
{
if ( read_pos == bytes_read )
{
read_pos = 0;
bytes_read = read( fd_in, buffer_in, 16 );
if ( bytes_read == -1 )
return EOF;
}
return (unsigned char)buffer_in[read_pos++];
}
请注意,您还必须更改变量声明
char ch;
在函数中main
int ch;
因为我们已将函数的返回值更改为 .buf_in
int
评论
0赞
ECH
12/5/2022
多谢!但是,有没有什么可以保持炭buf_in呢?
0赞
Andreas Wenzel
12/5/2022
@ECH:在未签名的平台上,您将无法用 表示值,因此您必须改用。在已签名的平台(大多数平台)上,如果使用 .因此,如果您希望程序可靠地工作,则必须使用 而不是 。char
EOF
char
int
char
EOF
char
int
char
评论
while((ch=buf_in())!= EOF)
buf_in
EOF
read
char
EOF
int
EOF
buf_in
read
EOF
buf_in
read_pos
write_pos