@huyl08
2016-09-13T12:06:32.000000Z
字数 6060
阅读 1378
C/C++
星迹迷航
文件读写
- 完整的C/C++示例源码可通过该链接下载
- 推荐使用Visual Studio或者CLion作为集成开发环境。
以下为C/C++源码样例
头文件coordinate.h
#include <string.h>
#include <stdlib.h>
#ifndef STARTREK_COORDINATE_H
#define STARTREK_COORDINATE_H
// 声明坐标结构体
struct _coordinate{
// 经度
double x;
// 纬度
double y;
};
// 声明坐标结构体指针
typedef struct _coordinate* coordinate;
// 声明坐标序列结构体
struct _coordinate_sequence{
// 坐标序列头指针
coordinate* sequence;
// 坐标序列当前大小
int sequence_size;
// 坐标序列容量大小
int sequence_capacity;
};
// 声明坐标序列结构体指针
typedef struct _coordinate_sequence* coordinate_sequence;
// 将输入字符串input_string按分隔符delim拆分,解析为一个坐标序列返回
coordinate_sequence geometry_parse(char* input_string, char* delim);
// 将输入字符串转化为一个坐标
coordinate point_parse(char* input_string);
// 调整坐标序列的容量,以2为倍数放大坐标序列容量
coordinate_sequence resize_coordinates(coordinate_sequence origin);
#endif //STARTREK_COORDINATE_H
源文件coordinate.c
#include "coordinate.h"
coordinate_sequence geometry_parse(char* input_string, char* delim){
// 使用malloc方法分配内存空间
coordinate_sequence result = (coordinate_sequence) malloc ( sizeof( struct _coordinate_sequence ) );
// 初始化当前坐标序列的容量、大小和坐标头指针
result->sequence_capacity = 4;
result->sequence_size = 0;
result->sequence = (coordinate*) malloc ( result->sequence_capacity * sizeof(struct _coordinate) );
// 将坐标指针指向的空间快速初始化
memset(result->sequence, 0, result->sequence_capacity * sizeof( struct _coordinate) );
// 初始化字符串分割的上下文变量
int context_size = 4096;
char** context = (char**) malloc ( context_size * sizeof( char* ) );
// 使用strtok_r分割输入字符串
char* buffer = strtok_r(input_string, delim, context);
// 当分割有效时,重复解析过程
while( buffer != NULL ){
// 将当前字符串解析为坐标
coordinate intermediate = point_parse(buffer);
// 坐标序列的复制和大小增加
result->sequence[result->sequence_size] = intermediate;
result->sequence_size++;
// 坐标序列大小达到容量,则进行扩容
if( result->sequence_size == result->sequence_capacity )
result = resize_coordinates(result);
// 继续拆分当前序列
buffer = strtok_r(NULL, delim, context);
}
return result;
}
coordinate point_parse(char* input_string){
coordinate result = (coordinate) malloc ( sizeof( struct _coordinate ) );
int context_size = 24;
char** context = (char**) malloc ( context_size * sizeof( char* ) );
// 使用":"分割输入字符串input_string为两个变量,并分别用atof方法将字符串数组转化为浮点数
char* buffer = strtok_r(input_string, ":", context);
result->x = atof(buffer);
buffer = strtok_r(NULL, ":", context);
result->y = atof(buffer);
return result;
}
coordinate_sequence resize_coordinates(coordinate_sequence origin){
// 初始化新坐标序列的内存
coordinate_sequence target = (coordinate_sequence) malloc( sizeof( struct _coordinate_sequence) );
// 新坐标序列按2倍扩容
target->sequence_capacity = 2 * origin->sequence_capacity;
target->sequence_size = origin->sequence_size;
target->sequence = (coordinate*) malloc( target->sequence_capacity * sizeof( struct _coordinate) );
// 快速初始化新坐标序列的内存
memset( target->sequence, 0, target->sequence_capacity * sizeof( struct _coordinate ) );
// 将原有的坐标拷贝到新坐标序列中
for( int i = 0 ; i < target->sequence_size; i++ )
target->sequence[i] = origin->sequence[i];
// 释放旧坐标序列的指针
free(origin);
origin = NULL;
return target;
}
头文件link.h
#include "coordinate.h"
#include <stdio.h>
#ifndef STARTREK_LINK_H
#define STARTREK_LINK_H
// 声明路段结构体
struct _link{
// 路段编号
int link_id;
// 起始点编号
int from_node;
// 终止点编号
int to_node;
// 道路等级
int link_class;
// 道路长度
double link_length;
// 道路坐标序列
coordinate_sequence coordinates;
};
// 声明路段结构体指针
typedef struct _link* link;
// 声明路段序列结构体
struct _link_sequence{
int sequence_size;
int sequence_capacity;
link* sequence;
};
// 声明路段序列结构体指针
typedef struct _link_sequence* link_sequence;
// 根据输入位置link_file读入文件
link_sequence read_link(char* link_file);
// 调整路段序列容量
link_sequence resize_links(link_sequence origin);
#endif //STARTREK_LINK_H
源文件link.c
#include "link.h"
link_sequence read_link(char* link_file){
// 分配路段序列内存
link_sequence result = (link_sequence) malloc ( sizeof( struct _link_sequence) );
// 初始化路段序列的容量、大小和路段头指针
result->sequence_capacity = 10;
result->sequence_size = 0;
result->sequence = (link*) malloc ( result->sequence_capacity * sizeof(link) );
// 快速初始化路段序列
memset( result->sequence, 0, result->sequence_capacity * sizeof(link));
// 打开文件指针
FILE* file = fopen(link_file, "r");
// 文件不存在,返回空指针
if( file == NULL ){
printf("Faile to open file \"%s\"", link_file);
return NULL;
}
// 声明文件输入缓存变量
int buffer_size = 4096;
char* buffer = (char*) malloc ( buffer_size * sizeof(char) );
char* gets_return = fgets(buffer, buffer_size, file);
// 按行读取数据
while( gets_return != NULL ){
// 按","拆分当前行
char* token = strtok(buffer, ",");
// 生成路段结构体指针
link link_new = (link) malloc ( sizeof(struct _link) );
// 解析路段信息
link_new->link_id = atoi(token);
token = strtok(NULL, ",");
link_new->from_node = atoi(token);
token = strtok(NULL, ",");
link_new->to_node = atoi(token);
token = strtok(NULL, ",");
link_new->link_length = atof(token);
token = strtok(NULL, ",");
link_new->link_class = atoi(token);
token = strtok(NULL, ",");
link_new->coordinates = geometry_parse(token, ";");
// 将新路段赋值给路段序列,路段序列大小增加
result->sequence[result->sequence_size] = link_new;
result->sequence_size++;
// 路段序列大小达到容量,进行扩容
if( result->sequence_size == result->sequence_capacity )
result = resize_links(result);
// 读取新的一行
gets_return = fgets(buffer, buffer_size, file);
}
// 关闭文件指针
fclose(file);
file = NULL;
return result;
}
link_sequence resize_links(link_sequence origin){
// 初始化新的路段序列指针内存
link_sequence target = (link_sequence) malloc ( sizeof( struct _link_sequence) );
// 初始化新的路段序列的容量、大小和头指针,容量按2倍比例扩容
target->sequence_capacity = 2 * origin->sequence_capacity;
target->sequence_size = origin->sequence_size;
target->sequence = (link*) malloc ( target->sequence_capacity * sizeof( struct _link) );
// 快速初始化头指针内存空间
memset(target->sequence, 0, target->sequence_capacity * sizeof( struct _link));
// 原有路段赋值给新的路段序列
for( int i = 0 ; i < target->sequence_size; i++ )
target->sequence[i] = origin->sequence[i];
// 释放旧的路段序列指针
free(origin);
origin = NULL;
return target;
}
头文件main.h
#include "link.h"
#include <stdio.h>
#ifndef STARTREK_MAIN_H
#define STARTREK_MAIN_H
int main();
#endif //STARTREK_MAIN_H
源文件main.c
#include "main.h"
int main() {
// 读入路段序列
link_sequence star_trek = read_link("gis.txt");
return 0;
}
1,3,4,280.3,2,115.488988:39.917917;115.488997:39.917938;115.489045:39.918061;115.489219:39.918316;115.489335:39.918486;115.489366:39.918540;115.489382:39.918612;115.489385:39.918672;115.489373:39.918713
3,7,8,173.2,2,115.381547:39.950776;115.381786:39.950461;115.381848:39.950355;115.381887:39.950260;115.381913:39.950163
57952495354,20160701120100,116.372966,39.908912,26.00,262
13381083463,20160701120147,116.387472,39.889589,26.00,266
13311492120,20160701120144,116.355589,39.993436,10.00,260
13439610594,20160701120147,116.394988,39.940625,0.00,0