C程序打印最后一行两次(文件I/O)
最近我在读Deitel出版的《C如何编程》第七版的文件处理部分。对于写入文件,它使用以下示例:C程序打印最后一行两次(文件I/O),c,C,最近我在读Deitel出版的《C如何编程》第七版的文件处理部分。对于写入文件,它使用以下示例: // Fig. 11.2: fig11_02.c // Creating a sequential file #include <stdio.h> int main( void ) { unsigned int account; // account number char name[ 30 ]; // account name double balance; //
// Fig. 11.2: fig11_02.c
// Creating a sequential file
#include <stdio.h>
int main( void )
{
unsigned int account; // account number
char name[ 30 ]; // account name
double balance; // account balance
FILE *cfPtr; // cfPtr = clients.dat file pointer
// fopen opens file. Exit program if unable to create file
if ( ( cfPtr = fopen( "clients.dat", "w" ) ) == NULL ) {
puts( "File could not be opened" );
} // end if
else {
puts( "Enter the account, name, and balance." );
puts( "Enter EOF to end input." );
printf( "%s", "? " );
scanf( "%d%29s%lf", &account, name, &balance );
// write account, name and balance into file with fprintf
while ( !feof( stdin ) ) {
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
scanf( "%d%29s%lf", &account, name, &balance );
} // end while
fclose( cfPtr ); // fclose closes file
} // end else
} // end main
输出:
1 test 25.6
2 some 95
2 some 95
改为:
else {
puts( "Enter the account, name, and balance." );
puts( "Enter to end input." );
// write account, name and balance into file with fprintf
while (scanf( "%d%29s%lf", &account, name, &balance)==3)
{
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
}
fclose( cfPtr ); // fclose closes file
} // end else
关键是EOF测试必须始终遵循scanf(),并且必须在打印读取信息之前进行 if-else条件仅用于处理最终的打开错误条件,因此您如何修改代码并不完全清楚。然而,人们经常尝试这样做:
while ( !feof( stdin ) ) {
scanf( "%d%29s%lf", &account, name, &balance );
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
}
这是错误的,因为当读取最后一个数据时,它不会“读取EOF”(EOF是您完成读取数据后满足的条件):只有后续的scanf()
会执行,并且输出函数会打印错误的数据(之前的函数不会因为输入错误而被覆盖,这就是为什么最后一行会重复)
例如,这是正确的:
for ( ;; ) {
scanf( "%d%29s%lf", &account, name, &balance );
if (feof( stdin )) break;
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
}
实际上,我更喜欢它,而不是像Deitel建议的那样重复两次相同的scanf()
行 更正的代码为:
while ( !feof( stdin ) ) {
if( !feof( stdin ) )
{
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
scanf( "%d%29s%lf", &account, name, &balance );
}
}
可能与我读到的内容重复,但我认为我的情况不同。在您完成
main
函数之前,您应该输入返回0代码>,或一些数字。显示您的输入(数据和EOF)。对于unsigned int
也使用%u
可以显示您遇到问题的代码(显示代码,而不是代码的英文描述)。看起来你已经发布了工作代码,而不是坏代码。阅读文档(习惯于查找内容-这很有帮助)。
while ( !feof( stdin ) ) {
if( !feof( stdin ) )
{
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "%s", "? " );
scanf( "%d%29s%lf", &account, name, &balance );
}
}