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