#include "offsetFinder.h"
/** Reads a GIS record file (as described in the corresponding project
* specification), and determines, for each GIS record contained in that
* file, the offset at which that record begins. The offsets are stored
* into an array supplied by the caller.
*
* Pre: gisFile is open on a GIS record file
* offsets[] is an array large enough to hold the offsets
* Post: offsets[] contains the GIS record offsets, in the order
* the records occur in the file
* Returns: the number of offsets that were stored in offsets[]
*/
uint32_t findOffsets(FILE* gisFile, uint32_t offsets[]) {
FILE *op;
/*** Complete the implementation of this function ***/
int count = 0;
char offsets[1000];
char *reader;
op = fopen(gisFile, "r");
if (!op) {
perror("Failed to open file!\n");
exit(1);
}
else {
reader = offsets;
while (*reader != '\n' && fgets(offsets, sizeof(offsets), op)) {
count++;
}
}
return count;
}大家好,我有一个关于这个作业的问题。这样的设置正确吗?对于GISData.txt,我应该读取整个文件,并且必须返回存储在offsets[]中的偏移量。
FEATURE_ID|FEATURE_NAME|FEATURE_CLASS|STATE_ALPHA|STATE_NUMERIC|COUNTY_NAME|COUNTY_NUMERIC|PRIMARY_LAT_DMS|PRIM_LONG_DMS|PRIM_LAT_DEC|PRIM_LONG_DEC|SOURCE_LAT_DMS|SOURCE_LONG_DMS|SOURCE_LAT_DEC|SOURCE_LONG_DEC|ELEV_IN_M|ELEV_IN_FT|MAP_NAME|DATE_CREATED|DATE_EDITED
885513|Siegrest Draw|Valley|NM|35|Eddy|015|323815N|1043256W|32.6376116|-104.5488549|323859N|1043732W|32.6498321|-104.6255227|1095|3592|Parish Ranch|11/13/1980|
885526|AAA Tank|Reservoir|NM|35|Eddy|015|321043N|1041456W|32.1786543|-104.2489615|||||1006|3300|Bond Draw|11/13/1980|06/23/2011
885566|Adobe Draw|Valley|NM|35|Eddy|015|322820N|1042141W|32.4723375|-104.361345|322704N|1042129W|32.4511111|-104.3580556|1007|3304|Carlsbad West|11/13/1980|
885567|Adobe Flat|Flat|NM|35|Eddy|015|322849N|1042119W|32.4803932|-104.3552339|||||1006|3300|Carlsbad West|11/13/1980|
885607|Alacran Hills|Range|NM|35|Eddy|015|322812N|1041055W|32.4701183|-104.1818931|||||1009|3310|Carlsbad East|11/13/1980|
885684|Alkali Lake|Lake|NM|35|Eddy|015|323039N|1041133W|32.5109371|-104.1924802|||||966|3169|Angel Draw|11/13/1980|06/23/2011
885697|Allen Well|Well|NM|35|Eddy|015|322309N|1042120W|32.3859489|-104.3555084|||||1038|3405|Carlsbad West|11/13/1980|这是地理信息系统的一个片段,每个区域数据(一行)都被认为是一条GISData.txt记录。“赋值中提到的偏移量是GIS数据文件中GIS记录的开始位置。
由于每条GIS记录占用整行,因此GIS记录的偏移量仅仅是GIS记录中第一个字节的偏移量。
当然,GIS数据文件的第一行不包含GIS记录,因此在偏移量0处没有GIS记录。“
如果我完全错了,有人能检查一下我的代码并修改它吗?谢谢你!!
发布于 2021-03-16 20:24:08
“对于GISData.txt,我应该通读整个文件,我必须返回存储在offsets[]....Can中的偏移量,如果我完全错了,有人检查我的代码并修改它?”
首先,在这个问题中,似乎对偏移的含义有一些混淆。而且,在谷歌上搜索"gid offset“之后,我可以理解为什么。这是a GIS specific definition
_“偏移量
地图学在地图学中,地物的位移或运动,使它们在以给定比例显示时不会重叠。
例如,如果符号足够宽以至于它们重叠,则道路可以从河流偏移。
符号系统在符号系统中,符号的原点或插入点在x和/或y方向上的移位。ESRI软件在ArcGIS中,将场景中的表面或要素的z值更改为恒定量或
通过使用表达式。可以应用偏移来使要素恰好绘制在表面之上。“_
而这个“C语言的地理信息系统”definition
“文件可以被看作是一个字节序列,每个字节位于文件开头的唯一偏移量,就像数组的单元格一样。因此,每条地理信息系统记录从文件开头的唯一偏移量开始。”
这两个定义虽然都源于对gis偏移的搜索,但它们是如此不同,以至于在这个问题中没有对这两个术语的含义提供任何澄清。出于这个回答的目的,我将从您在评论中的响应中获取我的队列,并将解决如何解析文件的每个记录中的第一个字段。(不包括第1行中的标题记录。)
这里有一些建议的步骤,可以用来实现这一点。
要考虑的步骤:
原型设计如注释中所述,原型向findOffsets()函数应提供以下内容:filespec、数组大小、数组。注释中没有提到,但也可能有用的是将读取的最长记录的长度。例如:
uint32_t findOffsets(const char *fileSpec, size_t longestElement, size_t numElements, uint32_t offsets[numElements]);调用函数产生的
numRecords。看见int count_names(const char *filename, size_t *count){...}
示例here,例如如何读取记录的数量(以及当需要时获取最长的记录)。在文件中。完成后关闭文件:
示例:
uint32_t offsets[numRecords-1]; //-1 skipping header line
memset(records, 0, sizeof records);findOffsets()示例:
size_t numOffsets = sizeof records/sizeof *records
uint32_t count = findOffsets("c:\\gis\\data.gis", longestRecord, numOffsets, offsets);
if(count > 0)
{
//do something with records
} findOffsets()中的
的打开文件
下面是一个代码示例(具有非常有限的安全性/错误检查),展示了如何做到这一点。它使用您的示例文件内容进行了测试,并借用了上面链接的代码,以适应此目的:
const char *fileSpec = "C:\\some_directory\\gisData.gis";
uint32_t findOffsets(const char *fileSpec, size_t longestElement, size_t numElements, uint32_t offsets[numElements]);
int count_lines_in_file(const char *filename, size_t *count);
size_t filesize(const char *fn);
int main(void)
{
size_t numRecords = 0;
int longestRecord = count_lines_in_file(fileSpec, &numRecords)+1;//+1 room for null terminator
uint32_t offsets[numRecords -1];//-1 - skipping header line
memset(offsets, 0, sizeof offsets);//initialize VLA offsets
int recordsProcessed = findOffsets(fileSpec, longestRecord, numRecords -1, offsets);//do the work
return 0;
}
uint32_t findOffsets(const char *fileSpec, size_t longestElement, size_t numElements, uint32_t offsets[numElements])
{
char *delim = "|";
char *tok = NULL;
char line[longestElement+1]; //+1 - room for null terminator during read.
memset(line, 0, sizeof line);//initialize VLA line to all zeros
int inx = 0;
FILE *fp = fopen(fileSpec, "r");
if(fp)
{
while(fgets(line, sizeof line, fp))//loop to read all lines in file
{
if(!strstr(line, "FEATURE_ID"))//skip header line, process all other lines
{
tok = strtok(line, delim);//extract first field
if(tok)
{
offsets[inx] = atoi(tok);//convert token and store number
inx++;
}
}
}
fclose(fp);
}
return inx;
}
//passes back count of lines in file, and return longest line
int count_lines_in_file(const char *filename, size_t *count)
{
int len=0, lenKeep = 0;
FILE *fp = fopen(filename, "r");
if(fp)
{
char *tok = NULL;
char *delim = "\n";
int cnt = 0;
size_t fSize = filesize(filename);
char *buf = calloc(fSize, 1);
while(fgets(buf, fSize, fp)) //goes to newline for each get
{
tok = strtok(buf, delim);
while(tok)
{
cnt++;
len = strlen(tok);
if(lenKeep < len) lenKeep = len;
tok = strtok(NULL, delim);
}
}
*count = cnt;
fclose(fp);
free(buf);
}
return lenKeep;
}
//return file size in bytes (binary read)
size_t filesize(const char *fn)
{
size_t size = 0;
FILE*fp = fopen(fn, "rb");
if(fp)
{
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
fclose(fp);
}
return size;
}https://stackoverflow.com/questions/66644467
复制相似问题