fseek() 将指针设置到错误的位置
fseek() sets the pointer to wrong position
我有一个具有以下结构的 .dat 文件:
Object name | Area | Length |Form Factor
我正在尝试查找哪个对象具有最小面积。我读取了整个文件并使用 ftell() 跟踪具有最小面积的对象及其位置。当我读完文件后,我将流位置指示器设置为我从 ftell() 获得的任何值。然后我读了那一行作为我的最终结果,但现在,我读错了行。
objects.dat:
toy1 12785.00 550.70 23.22
toy2 11506.50 495.63 0.48
Pen 35008.65 1450.98 0.17
Pencil 42788.35 1773.42 0.209
card7 128433.00 1552.67 0.67
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
FILE *cfPtr;
errno_t err;
char name[15];
double area, length, fF;
double minArea = 100000.0;
long address, minAreaAdd;
char string[100];
if ((err = fopen_s(&cfPtr, "objects.dat", "r")) != 0) // Check if we can reach the file
printf("The file 'objecs.dat' was not opened to read.\n");
else
{
while (fgets(string, 100, cfPtr))
{
address = ftell(cfPtr);
sscanf_s(string,"%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
if (area < minArea)
{
minArea = area;
minAreaAdd = address;
}
}
cout << "Min Area: " << minArea << " Address: " << minAreaAdd << "\n\n";
fseek(cfPtr, minAreaAdd, SEEK_SET);
fgets(string, 100, cfPtr);
sscanf_s(string, "%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
cout << "Name: " << name << " Area : " << area << " Length: " << length << " Form factor: " << fF << "\n";
fclose(cfPtr);
}
return 0;
}
输出:
Min Area: 11506.5 Address: 55
Name: Pen Area : 35008.7 Length: 1450.98 Form factor: 0.17
当您获得文件位置并将其存储到 address
时,那是在您读入该行之后,因此当您寻求它以获取答案时,您将获得该行 [=13] =]在之后是正确的。
如“1201ProgramAlarm”所述,您在读取要保存的行后获取地址。也就是说,您在 fgets
.
之后使用 ftell
发生的事情是 fgets
在读取数据时移动了文件位置指示器。这是因为fgets
需要为下一次读取操作准备文件,否则你会卡在同一个位置,读取相同的数据。
你需要扭转这个逻辑。这是一个例子:
address = -1
do
{
if (address >= 0) {
sscanf_s(string,"%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
if (area < minArea)
{
minArea = area;
minAreaAdd = address;
}
}
address = ftell(cfPtr);
} while (ret = fgets(string, 100, cfPtr));
我有一个具有以下结构的 .dat 文件:
Object name | Area | Length |Form Factor
我正在尝试查找哪个对象具有最小面积。我读取了整个文件并使用 ftell() 跟踪具有最小面积的对象及其位置。当我读完文件后,我将流位置指示器设置为我从 ftell() 获得的任何值。然后我读了那一行作为我的最终结果,但现在,我读错了行。
objects.dat:
toy1 12785.00 550.70 23.22
toy2 11506.50 495.63 0.48
Pen 35008.65 1450.98 0.17
Pencil 42788.35 1773.42 0.209
card7 128433.00 1552.67 0.67
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
FILE *cfPtr;
errno_t err;
char name[15];
double area, length, fF;
double minArea = 100000.0;
long address, minAreaAdd;
char string[100];
if ((err = fopen_s(&cfPtr, "objects.dat", "r")) != 0) // Check if we can reach the file
printf("The file 'objecs.dat' was not opened to read.\n");
else
{
while (fgets(string, 100, cfPtr))
{
address = ftell(cfPtr);
sscanf_s(string,"%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
if (area < minArea)
{
minArea = area;
minAreaAdd = address;
}
}
cout << "Min Area: " << minArea << " Address: " << minAreaAdd << "\n\n";
fseek(cfPtr, minAreaAdd, SEEK_SET);
fgets(string, 100, cfPtr);
sscanf_s(string, "%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
cout << "Name: " << name << " Area : " << area << " Length: " << length << " Form factor: " << fF << "\n";
fclose(cfPtr);
}
return 0;
}
输出:
Min Area: 11506.5 Address: 55
Name: Pen Area : 35008.7 Length: 1450.98 Form factor: 0.17
当您获得文件位置并将其存储到 address
时,那是在您读入该行之后,因此当您寻求它以获取答案时,您将获得该行 [=13] =]在之后是正确的。
如“1201ProgramAlarm”所述,您在读取要保存的行后获取地址。也就是说,您在 fgets
.
ftell
发生的事情是 fgets
在读取数据时移动了文件位置指示器。这是因为fgets
需要为下一次读取操作准备文件,否则你会卡在同一个位置,读取相同的数据。
你需要扭转这个逻辑。这是一个例子:
address = -1
do
{
if (address >= 0) {
sscanf_s(string,"%s %lf %lf %lf", &name, sizeof name, &area, &length, &fF);
if (area < minArea)
{
minArea = area;
minAreaAdd = address;
}
}
address = ftell(cfPtr);
} while (ret = fgets(string, 100, cfPtr));