C 额外EOF字符

C 额外EOF字符,c,feof,C,Feof,我有一个程序,可以将文件读入缓冲区结构。我遇到的问题是,当我查看文件的输出时,末尾有一个额外的EOF字符。我将发布相关函数:(注意:我删除了参数检查,只发布了与问题相关的函数中的代码) b_载荷 int b_load(FILE * const fi, Buffer * const pBD){ unsigned char character; /*Variable to hold read character from file*/ Buffer * tempBuffer; /*T

我有一个程序,可以将文件读入缓冲区结构。我遇到的问题是,当我查看文件的输出时,末尾有一个额外的EOF字符。我将发布相关函数:(注意:我删除了参数检查,只发布了与问题相关的函数中的代码)

b_载荷

int b_load(FILE * const fi, Buffer * const pBD){
    unsigned char character; /*Variable to hold read character from file*/
    Buffer * tempBuffer; /*Temparary Bufer * to prevent descruction of main Buffer*/
    short num_chars = 0; /*Counter of the amount of characters read into the buffer*/

    /*Assigns main Buffer to tempBuffer*/
    tempBuffer = pBD;

    /*Infinite loop that breaks after EOF is read*/
    while(1){
        /*calls fgetc() and returns the char into the character variable*/
        character = (unsigned char)fgetc(fi);

        if(!feof(fi)){
            tempBuffer = b_addc(pBD,character);

            if(tempBuffer == NULL)
                return LOAD_FAIL;
            ++num_chars;
        }else{  
            break;
        }
    }
    return num_chars;
}    
b_打印

int b_print(Buffer * const pBD){
    int num_chars = 0;

    if(pBD->addc_offset == 0)
        printf("The buffer is empty\n");
    /*Sets getc_offset to 0*/
    b_set_getc_offset(pBD, 0);

    pBD->eob=0;

    /*b_eob returns the structures eob field*/
    while (!b_eob(pBD)){
        printf("%c",b_getc(pBD));
        ++num_chars;
    }
    printf("\n");

    return num_chars;
}
b_getc

char b_getc(Buffer * const pBD){
    if(pBD->getc_offset  == pBD->addc_offset){
        pBD->eob = 1;
        return R_FAIL_1;
    }   
    pBD->eob = 0;
    return pBD->ca_head[(pBD->getc_offset)++];
}
最后,我得出以下结论:

“猫” (y是EOF字符)

它打印一个EOF字符,但从未添加到缓冲区。当驱动程序代码将EOF字符添加到缓冲区末尾时,将显示2。你知道这是什么原因吗?我可能使用了
feof()
错误,所以可能是这样,但在代码中它是必需的没有“EOF字符”
EOF
是由
getchar()
和相关函数返回的值,表示它们没有更多的输入可读取。它是一个扩展为负整数常量表达式的宏,通常为
(-1)

(对于Windows文本文件,文件中的Control-Z字符可能会触发文件结束条件。如果在文本模式下读取此类文件,您将看不到该字符;它将表现为在该点到达文件结尾。)

不要使用
feof()
函数检测没有更多的输入可读取。相反,请查看您正在使用的任何输入函数返回的值。不同的输入函数使用不同的方式表示它们无法读取任何内容;请阅读您正在使用的文档。例如,
fgets()

例如,
getchar()
,返回它刚刚读取的字符(作为
无符号字符处理并转换为
int
)或值
EOF
,以指示它无法读取任何内容。选择
EOF
的负值是为了避免与
unsigned char
类型的任何有效值冲突。这意味着您需要将
getchar()
返回的值存储在
int
对象中;如果将其存储在
字符
无符号字符
中,则可能会丢失信息,并且值为
0xff
的实际字符可能会被误认为
EOF

函数的作用是:返回正在读取的文件的文件结束指示器的值。在尝试读取文件但失败后,该指示器变为真。如果由于错误而没有输入,而不是由于文件结束条件,
feof()
将永远不会变为真

您可以使用
feof()
和/或
ferror()
确定没有更多输入可读取的原因,但只能在通过其他方式检测到输入后进行

推荐阅读:本手册第12节,其中包括stdio。(还有其他部分。)

更新:

我对您的代码了解不够,无法理解您在使用
缓冲区
对象做什么。您的输入外观实际上看起来(几乎)正确,尽管它的书写方式很笨拙

从文件中读取字符的常用习惯用法是:

int c;   /* `int`, NOT `char` or `unsigned char` */
while ((c = fgetc(fi)) != EOF) {
    /* process character in `c` */
}
但是你的方法,我可能会这样重新安排:

while (1) {
    c = fgetc(fi);
    if (feof(fi) || ferror(fi)) {
        /* no more input */
        break;
    }
    /* process character in c */
}
应该真的管用。注意,我已经为
ferror(f1)
添加了一个检查。是否可能是输入错误(您没有检测到)?这将导致
c
包含
EOF
,或者
EOF
的值转换为
c
的类型。这是值得怀疑的,因为它可能会给你一个无限循环

建议的方法:使用交互式调试器或添加的
printf
调用,每次通过循环显示
字符的值。如果您的输入循环工作正常,则使用对
b_addc()
的硬连线调用序列构建一个精简版本的程序,并查看是否可以通过这种方式重现问题。

没有“EOF字符”
EOF
是由
getchar()
和相关函数返回的值,表示它们没有更多的输入可读取。它是一个扩展为负整数常量表达式的宏,通常为
(-1)

(对于Windows文本文件,文件中的Control-Z字符可能会触发文件结束条件。如果在文本模式下读取此类文件,您将看不到该字符;它将表现为在该点到达文件结尾。)

不要使用
feof()
函数检测没有更多的输入可读取。相反,请查看您正在使用的任何输入函数返回的值。不同的输入函数使用不同的方式表示它们无法读取任何内容;请阅读您正在使用的文档。例如,
fgets()

例如,
getchar()
,返回它刚刚读取的字符(作为
无符号字符处理并转换为
int
)或值
EOF
,以指示它无法读取任何内容。选择
EOF
的负值是为了避免与
unsigned char
类型的任何有效值冲突。这意味着您需要将
getchar()
返回的值存储在
int
对象中;如果将其存储在
字符
无符号字符
中,则可能会丢失信息,并且值为
0xff
的实际字符可能会被误认为
EOF

函数的作用是:返回正在读取的文件的文件结束指示器的值。当你完成tri后,该指标变为真
int b_load(FILE * const fi, Buffer * const pBD){
    int character; /*Variable to hold read character from file*/
    Buffer * tempBuffer; /*Temparary Bufer * to prevent descruction of main Buffer*/
    short num_chars ; /*Counter of the amount of characters read into the buffer*/


    /*Infinite loop that breaks WHEN EOF is read*/
    while(num_chars = 0; 1; num_chars++ ) {

        character = fgetc(fi);
        if (character == EOF || feof(fi)) break; // since you insist on the silly feof() ...

        tempBuffer = b_addc(pBD, (unsigned char) character);
        if(tempBuffer == NULL) return LOAD_FAIL;
        }
    }
    return num_chars;
}