【发布时间】:2022-01-14 08:54:21
【问题描述】:
我想用 fscanf 在文本文件中进行搜索。 这是我正在搜索的数字,这些数字按值排序。 因此,我想做一个二分查找,从中间开始等等。 我的想法是先计算行数,除以二找到中间。 但是如何告诉 fscanf 看那行呢?
int seach_textfile(struct data *ean13, unsigned long long int *input)
{
FILE *fp_read = fopen("data.tex", "r");
unsigned long long int read, n_lines;
// count lines
n_lines = 0;
while (fscanf(fp_read,"\n") == 1)
{
n_lines++;
}
int n_line_low = 0;
int n_line_mid;
int n_line_high =n_lines;
while(n_line_high>n_line_low)
{
n_line_mid; = (n_line_low + n_line_high)/2;
fscanf(fp_read,"%lld \n", read).... at n_line_mid // <----here!! (only to read first entr on line)
if(*input > read)
{
n_line_low = n_line_mid +1;
}
else
{
n_line_high = n_line_mid;
}
}
if(*input == read)
{
fscanf(fp_read,"%lld %s %s %s",*ean13->ean,*ean13->country,*ean13->manufacture,*ean13->product).... at n_line_mid // <----here!!
return 1;
}
else return 0;
}
【问题讨论】:
-
while (fscanf(fp_read,"\n") == 1)不计算 行。fscanf(fp_read,"\n")读取并使用所有前导空白。 -
您可以使用 fgets 逐行读取,对于读取的每一行(进入提供给 fgets 的缓冲区),使用 sscanf 在行中搜索。并测试函数的返回。
-
如果您愿意阅读整个文件以计算行数,为什么不一边阅读一边寻找信息?在二分搜索操作期间,您将如何避免读取所有行直到您要搜索的行号?请记住,行的长度变化很大。
-
除非您可以有效地移动到随机行的开头,否则您无法有效地对文件执行二进制搜索。这需要固定长度的行或索引。如果你有其中任何一个,那么你不需要读取文件来计算行数。如果您没有其中任何一个,那么简单地执行文件的线性扫描是最简单和最有效的,因为无论如何您都必须这样做才能计算行数或建立索引。
-
数字,作为文本,在文件中的间距不均匀。也许找到文件字节长度,然后应用二进制搜索。长度的每一半可能指向一行的中间,然后向后(或向前)搜索一行的开头,然后读取数字。我没有看到一个高度便携的解决方案来读取文本文件并通过二进制搜索查找是 UB。相反,可以读取记录每行开始在数组中的偏移量的文件,然后对该数组进行二进制搜索。祝你好运。