FEOF过早成为现实

feof becomes true prematurely

提问人:Dasonic 提问时间:8/28/2018 最后编辑:Dasonic 更新时间:8/28/2018 访问量:311

问:

我试图通过一次读取一个字符来通过套接字发送文件,直到缓冲区(字符数组)已满,发送它,然后重复直到文件结束。但是由于某种原因,feof 在文件结束之前变为 true(我相信可能是在缓冲区数组已满时)。

int c;
int end_loop = 1;
char to_send[BUFFER_LENGTH];
while (end_loop == 1) { //For the entire file
    printf("creating next data\n");
    bzero(to_send, BUFFER_LENGTH);
    for (int i = 0; i < BUFFER_LENGTH - 1; i++) { // read data from file until buffer full or EOF
        c = fgetc(f);
        if (c == EOF) { // If end of file break loop
            printf("EOF\n");
            end_loop = 0;
            break;
        }
        to_send[i] = c;
    }
    for (int i = 0; i < strlen(to_send); i++) {
        printf("%c", to_send[i]);
    }
    n = write(sockfd, to_send, strlen(to_send));
    if (n < 0) {
        perror("ERROR writing to socket");
        exit(1);
    }
}
n = write(sockfd, "EOF", 3);
if (n < 0) {
    perror("ERROR writing to socket\n");
    exit(1);
}

这是一个简单文件的输出client output

feof 可能不是问题,因为尽管满足了“EOF”,但代码似乎仍在循环。

编辑:从评论中添加了建议。仍然发生错误。

C fgets feof

评论

3赞 Some programmer dude 8/28/2018
您对文件结尾的检查有缺陷。您应该首先检查 fgetc 返回的内容。
1赞 Some programmer dude 8/28/2018
另请注意,打印和发送数据的代码并不关心输入的实际长度。您需要检查字符串的末尾(借助例如)。strlen
1赞 chux - Reinstate Monica 8/28/2018
c = fgetc(f); if (feof(f))是好奇的代码。如果由于罕见的错误而返回,循环将不会退出。建议“c = fgetc(f);if (c == EOF)'。fgetc()EOF
1赞 John Bollinger 8/28/2018
总体而言,并且不是主要用途的功能。应通过观察执行 I/O 的函数的返回值(例如 )来检测流中何时不再有可用数据。和 的主要用途是在事后区分已到达字符串的自然末端和流上发生的错误。feofferrorfgetcfeofferror
2赞 chux - Reinstate Monica 8/28/2018
@Someprogrammerdude 此处使用不是一种可靠的方法,因为可能包含 null 字符strlen()fgetc(f)

答:

1赞 chux - Reinstate Monica 8/28/2018 #1

代码需要跟踪读取的字符数,然后跟踪读取的字符数。printf(), write()

while (end_loop == 1) {
    ...
    // for (int i = 0; i < BUFFER_LENGTH - 1; i++) {
    int i;
    for (i = 0; i < BUFFER_LENGTH - 1; i++) { 
      ...
    }
    // for (int i = 0; i < BUFFER_LENGTH - 1; i++) {
    //    printf("%c", to_send[j]);
    for (int j = 0; j < i; j++) {
      ...
    // n = write(sockfd, to_send, BUFFER_LENGTH);
    n = write(sockfd, to_send, i);
    ...
}

其他问题包括

测试不仅EOFfeof(f)

    c = fgetc(f);
    // if (feof(f)) { // If end of file break loop 
    if (c == EOF) { // If end of file break loop **or input error**

填充数组时不需要 -1。-1 可能对字符串有用,但在这里使用字符串也不是最好的主意,因为可能会返回 null 字符charfgetc()

//                                   vvv 
// for (int i = 0; i < BUFFER_LENGTH - 1; i++)
for (int i = 0; i < BUFFER_LENGTH; i++)
// or better 
size_t i; 
for (i = 0; i < sizeof to_send; i++)

OP修改代码中间回答嗯。

不要使用 .读取的数据可能包含空字符,这否定了此处字符串的良好使用。for (int i = 0; i < strlen(to_send); i++) {


如果 OP 不想在最后一行之前看到,请在循环之后打印。"EOF\n""EOF\n"while

评论

0赞 Dasonic 8/28/2018
对不起,我的大部分困惑来自为什么 EOF 提前打印,然后我意识到这就是我写它的方式,并且该功能正在按照它的意图执行,而我的服务器行为不端。编辑是因为在建议之后我仍然认为我有问题,而事实上我没有,我是个白痴。
1赞 chux - Reinstate Monica 8/28/2018
@Dasonic 无需道歉或自我贬低。相反,向前支付