我试图思考如何读取文件的最后一行的逻辑,但我无法给出答案。ACCOUNTNUM信息是一个结构。我的.dat文件已经有3个acc号码了。在这里,我想知道如何得到最后一个帐号/行,即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 ú·发布于 2022-05-02 12:17:56
您可以在循环中调用fread,直到它返回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不会执行部分读取时,即当您确信文件大小是sizeof(ACCOUNTNUM)的确切倍数时,这才能保证工作。因为如果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[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 );
}发布于 2022-05-02 11:34:33
您正在逐个读取记录并将其存储在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的返回值,以确认对该文件的正确访问。还建议您在完成该文件后关闭该文件。
https://stackoverflow.com/questions/72085673
复制相似问题