C语言读取文件最后一行
Reading last line of a file In C
我正在思考如何读取文件最后一行的逻辑,但我想不出答案。 ACCOUNTNUM 信息是一个结构。 my .dat file who has 3 acc numbers already。在这里我想知道如何获取最后一个帐户 number/line 即 2022-3.
这是函数
LastAccountNumber(){
ACCOUNTNUM info;
file = fopen("acctNumbers.dat","r");
char firstAcc[50]="2022-1";//ignore this I was gonna compare this with the last line.
while((fread(&info,sizeof(struct accountNum),1,file))==1){
printf("\nAcc No %s",info.sAccountNum);
}
}
}
这是我的结构
struct accountNum{
int sequence;
char sAccountNum[16];
};
typedef struct accountNum ACCOUNTNUM;
我的 acctNumbers.dat 文件的内容。
2022-1 ú· 2022-2 ú· 2022-3 ú·
你是一条条读取记录存入info
,按理说循环结束时存入info
的元素ACCOUNTNUM
正好是最后一条记录在文件中,将以下代码稍作修改,以说明这一点:
#include <stdio.h>
struct accountNum {
int sequence;
char sAccountNum[16];
};
typedef struct accountNum ACCOUNTNUM;
int LastAccountNumber(ACCOUNTNUM* info) {
int success = 0;
FILE* file = fopen("acctNumbers.dat", "rb");
if (file == NULL) {
return -1; // Allows you to document different types of errors
}
while ((fread(info, sizeof(struct accountNum), 1, file)) == 1) {
success = 1;
}
fclose(file);
return success;
}
int main() {
ACCOUNTNUM N[] = {{123, "2022-1"}, {111, "2022-2"}, {321, "2022-3"}};
FILE* file = fopen("acctNumbers.dat", "wb");
fwrite(N, 1, sizeof N, file);
fclose(file);
ACCOUNTNUM info;
if (LastAccountNumber(&info) == 1) //if -1 couldn't open file, 0 no record read
printf("\nAcc No %s", info.sAccountNum);
}
将输出:
Acc No 2022-3
这正是文件中的最后一个元素。
实时样本:https://onlinegdb.com/q760Ow1vQc
请注意,您应该验证 fopen
的 return 值以确认对文件的正确访问。还建议在完成后关闭文件。
您可以循环调用 fread
直到它 returns 0
,然后打印读取的最后一条记录:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info;
bool success = false;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//skip to last record
while( ( fread( &info, sizeof info, 1, fp) ) == 1 )
{
//set variable to indicate that we have found at
//least one record
success = true;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info.sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}
但是,只有当您确定最后一个 fread
不会执行部分读取时,这才能保证有效,即如果您确定文件大小是 [=16= 的精确倍数].因为如果 fread
确实执行了部分读取,那么缓冲区内容将是不确定的。
如果不能排除部分读取的可能,那么可以使用两个buffer读取,交替使用:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info[2];
int current_index = 0;
bool success = false;
size_t ret;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
for (;;) //infinite loop, equivalent to while(1)
{
//read record from file
ret = fread( &info[current_index], sizeof *info, 1, fp);
//swap buffer index
current_index = current_index == 0 ? 1 : 0;
//restart loop if successful
if ( ret == 1 )
{
//set variable to indicate that we have found at
//least one record
success = true;
continue;
}
//break out of loop
break;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info[current_index].sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}
或者您可以使用单个缓冲区并通过交换函数的第二个和第三个参数来更改调用函数的方式 fread
,这样您就可以检测是否发生了部分读取。如果确实发生,您可以打印一条错误消息并终止程序。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info;
bool success = false;
size_t ret;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//read one record per loop iteration
while ( ( ret = fread( &info, 1, sizeof info, fp) ) != 0 )
{
//verify that no partial read occurred
if ( ret != sizeof info )
{
fprintf( stderr, "Error: Partial read detected!\n" );
exit( EXIT_FAILURE );
}
//set variable to indicate that we have found at
//least one record
success = true;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info.sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}
我正在思考如何读取文件最后一行的逻辑,但我想不出答案。 ACCOUNTNUM 信息是一个结构。 my .dat file who has 3 acc numbers already。在这里我想知道如何获取最后一个帐户 number/line 即 2022-3.
这是函数
LastAccountNumber(){
ACCOUNTNUM info;
file = fopen("acctNumbers.dat","r");
char firstAcc[50]="2022-1";//ignore this I was gonna compare this with the last line.
while((fread(&info,sizeof(struct accountNum),1,file))==1){
printf("\nAcc No %s",info.sAccountNum);
}
}
}
这是我的结构
struct accountNum{
int sequence;
char sAccountNum[16];
};
typedef struct accountNum ACCOUNTNUM;
我的 acctNumbers.dat 文件的内容。
2022-1 ú· 2022-2 ú· 2022-3 ú·
你是一条条读取记录存入info
,按理说循环结束时存入info
的元素ACCOUNTNUM
正好是最后一条记录在文件中,将以下代码稍作修改,以说明这一点:
#include <stdio.h>
struct accountNum {
int sequence;
char sAccountNum[16];
};
typedef struct accountNum ACCOUNTNUM;
int LastAccountNumber(ACCOUNTNUM* info) {
int success = 0;
FILE* file = fopen("acctNumbers.dat", "rb");
if (file == NULL) {
return -1; // Allows you to document different types of errors
}
while ((fread(info, sizeof(struct accountNum), 1, file)) == 1) {
success = 1;
}
fclose(file);
return success;
}
int main() {
ACCOUNTNUM N[] = {{123, "2022-1"}, {111, "2022-2"}, {321, "2022-3"}};
FILE* file = fopen("acctNumbers.dat", "wb");
fwrite(N, 1, sizeof N, file);
fclose(file);
ACCOUNTNUM info;
if (LastAccountNumber(&info) == 1) //if -1 couldn't open file, 0 no record read
printf("\nAcc No %s", info.sAccountNum);
}
将输出:
Acc No 2022-3
这正是文件中的最后一个元素。
实时样本:https://onlinegdb.com/q760Ow1vQc
请注意,您应该验证 fopen
的 return 值以确认对文件的正确访问。还建议在完成后关闭文件。
您可以循环调用 fread
直到它 returns 0
,然后打印读取的最后一条记录:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info;
bool success = false;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//skip to last record
while( ( fread( &info, sizeof info, 1, fp) ) == 1 )
{
//set variable to indicate that we have found at
//least one record
success = true;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info.sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}
但是,只有当您确定最后一个 fread
不会执行部分读取时,这才能保证有效,即如果您确定文件大小是 [=16= 的精确倍数].因为如果 fread
确实执行了部分读取,那么缓冲区内容将是不确定的。
如果不能排除部分读取的可能,那么可以使用两个buffer读取,交替使用:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info[2];
int current_index = 0;
bool success = false;
size_t ret;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
for (;;) //infinite loop, equivalent to while(1)
{
//read record from file
ret = fread( &info[current_index], sizeof *info, 1, fp);
//swap buffer index
current_index = current_index == 0 ? 1 : 0;
//restart loop if successful
if ( ret == 1 )
{
//set variable to indicate that we have found at
//least one record
success = true;
continue;
}
//break out of loop
break;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info[current_index].sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}
或者您可以使用单个缓冲区并通过交换函数的第二个和第三个参数来更改调用函数的方式 fread
,这样您就可以检测是否发生了部分读取。如果确实发生,您可以打印一条错误消息并终止程序。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct accountNum
{
int sequence;
char sAccountNum[16];
} ACCOUNTNUM;
int main( void )
{
FILE *fp;
ACCOUNTNUM info;
bool success = false;
size_t ret;
//open file and verify that it is open
fp = fopen( "acctNumbers.dat", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//read one record per loop iteration
while ( ( ret = fread( &info, 1, sizeof info, fp) ) != 0 )
{
//verify that no partial read occurred
if ( ret != sizeof info )
{
fprintf( stderr, "Error: Partial read detected!\n" );
exit( EXIT_FAILURE );
}
//set variable to indicate that we have found at
//least one record
success = true;
}
//print last record, if it exists
if ( success )
printf( "Acc No: %s\n", info.sAccountNum );
else
printf( "No records found.\n" );
//cleanup
fclose( fp );
}