[关闭]
@huyl08 2016-09-13T12:06:32.000000Z 字数 6060 阅读 1378

星迹迷航新手上路(C/C++版)

C/C++ 星迹迷航 文件读写


  1. 完整的C/C++示例源码可通过该链接下载
  2. 推荐使用Visual Studio或者CLion作为集成开发环境。

C/C++处理数据

以下为C/C++源码样例

坐标辅助类

头文件coordinate.h

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #ifndef STARTREK_COORDINATE_H
  4. #define STARTREK_COORDINATE_H
  5. // 声明坐标结构体
  6. struct _coordinate{
  7. // 经度
  8. double x;
  9. // 纬度
  10. double y;
  11. };
  12. // 声明坐标结构体指针
  13. typedef struct _coordinate* coordinate;
  14. // 声明坐标序列结构体
  15. struct _coordinate_sequence{
  16. // 坐标序列头指针
  17. coordinate* sequence;
  18. // 坐标序列当前大小
  19. int sequence_size;
  20. // 坐标序列容量大小
  21. int sequence_capacity;
  22. };
  23. // 声明坐标序列结构体指针
  24. typedef struct _coordinate_sequence* coordinate_sequence;
  25. // 将输入字符串input_string按分隔符delim拆分,解析为一个坐标序列返回
  26. coordinate_sequence geometry_parse(char* input_string, char* delim);
  27. // 将输入字符串转化为一个坐标
  28. coordinate point_parse(char* input_string);
  29. // 调整坐标序列的容量,以2为倍数放大坐标序列容量
  30. coordinate_sequence resize_coordinates(coordinate_sequence origin);
  31. #endif //STARTREK_COORDINATE_H

源文件coordinate.c

  1. #include "coordinate.h"
  2. coordinate_sequence geometry_parse(char* input_string, char* delim){
  3. // 使用malloc方法分配内存空间
  4. coordinate_sequence result = (coordinate_sequence) malloc ( sizeof( struct _coordinate_sequence ) );
  5. // 初始化当前坐标序列的容量、大小和坐标头指针
  6. result->sequence_capacity = 4;
  7. result->sequence_size = 0;
  8. result->sequence = (coordinate*) malloc ( result->sequence_capacity * sizeof(struct _coordinate) );
  9. // 将坐标指针指向的空间快速初始化
  10. memset(result->sequence, 0, result->sequence_capacity * sizeof( struct _coordinate) );
  11. // 初始化字符串分割的上下文变量
  12. int context_size = 4096;
  13. char** context = (char**) malloc ( context_size * sizeof( char* ) );
  14. // 使用strtok_r分割输入字符串
  15. char* buffer = strtok_r(input_string, delim, context);
  16. // 当分割有效时,重复解析过程
  17. while( buffer != NULL ){
  18. // 将当前字符串解析为坐标
  19. coordinate intermediate = point_parse(buffer);
  20. // 坐标序列的复制和大小增加
  21. result->sequence[result->sequence_size] = intermediate;
  22. result->sequence_size++;
  23. // 坐标序列大小达到容量,则进行扩容
  24. if( result->sequence_size == result->sequence_capacity )
  25. result = resize_coordinates(result);
  26. // 继续拆分当前序列
  27. buffer = strtok_r(NULL, delim, context);
  28. }
  29. return result;
  30. }
  31. coordinate point_parse(char* input_string){
  32. coordinate result = (coordinate) malloc ( sizeof( struct _coordinate ) );
  33. int context_size = 24;
  34. char** context = (char**) malloc ( context_size * sizeof( char* ) );
  35. // 使用":"分割输入字符串input_string为两个变量,并分别用atof方法将字符串数组转化为浮点数
  36. char* buffer = strtok_r(input_string, ":", context);
  37. result->x = atof(buffer);
  38. buffer = strtok_r(NULL, ":", context);
  39. result->y = atof(buffer);
  40. return result;
  41. }
  42. coordinate_sequence resize_coordinates(coordinate_sequence origin){
  43. // 初始化新坐标序列的内存
  44. coordinate_sequence target = (coordinate_sequence) malloc( sizeof( struct _coordinate_sequence) );
  45. // 新坐标序列按2倍扩容
  46. target->sequence_capacity = 2 * origin->sequence_capacity;
  47. target->sequence_size = origin->sequence_size;
  48. target->sequence = (coordinate*) malloc( target->sequence_capacity * sizeof( struct _coordinate) );
  49. // 快速初始化新坐标序列的内存
  50. memset( target->sequence, 0, target->sequence_capacity * sizeof( struct _coordinate ) );
  51. // 将原有的坐标拷贝到新坐标序列中
  52. for( int i = 0 ; i < target->sequence_size; i++ )
  53. target->sequence[i] = origin->sequence[i];
  54. // 释放旧坐标序列的指针
  55. free(origin);
  56. origin = NULL;
  57. return target;
  58. }

读取电子地图文件

头文件link.h

  1. #include "coordinate.h"
  2. #include <stdio.h>
  3. #ifndef STARTREK_LINK_H
  4. #define STARTREK_LINK_H
  5. // 声明路段结构体
  6. struct _link{
  7. // 路段编号
  8. int link_id;
  9. // 起始点编号
  10. int from_node;
  11. // 终止点编号
  12. int to_node;
  13. // 道路等级
  14. int link_class;
  15. // 道路长度
  16. double link_length;
  17. // 道路坐标序列
  18. coordinate_sequence coordinates;
  19. };
  20. // 声明路段结构体指针
  21. typedef struct _link* link;
  22. // 声明路段序列结构体
  23. struct _link_sequence{
  24. int sequence_size;
  25. int sequence_capacity;
  26. link* sequence;
  27. };
  28. // 声明路段序列结构体指针
  29. typedef struct _link_sequence* link_sequence;
  30. // 根据输入位置link_file读入文件
  31. link_sequence read_link(char* link_file);
  32. // 调整路段序列容量
  33. link_sequence resize_links(link_sequence origin);
  34. #endif //STARTREK_LINK_H

源文件link.c

  1. #include "link.h"
  2. link_sequence read_link(char* link_file){
  3. // 分配路段序列内存
  4. link_sequence result = (link_sequence) malloc ( sizeof( struct _link_sequence) );
  5. // 初始化路段序列的容量、大小和路段头指针
  6. result->sequence_capacity = 10;
  7. result->sequence_size = 0;
  8. result->sequence = (link*) malloc ( result->sequence_capacity * sizeof(link) );
  9. // 快速初始化路段序列
  10. memset( result->sequence, 0, result->sequence_capacity * sizeof(link));
  11. // 打开文件指针
  12. FILE* file = fopen(link_file, "r");
  13. // 文件不存在,返回空指针
  14. if( file == NULL ){
  15. printf("Faile to open file \"%s\"", link_file);
  16. return NULL;
  17. }
  18. // 声明文件输入缓存变量
  19. int buffer_size = 4096;
  20. char* buffer = (char*) malloc ( buffer_size * sizeof(char) );
  21. char* gets_return = fgets(buffer, buffer_size, file);
  22. // 按行读取数据
  23. while( gets_return != NULL ){
  24. // 按","拆分当前行
  25. char* token = strtok(buffer, ",");
  26. // 生成路段结构体指针
  27. link link_new = (link) malloc ( sizeof(struct _link) );
  28. // 解析路段信息
  29. link_new->link_id = atoi(token);
  30. token = strtok(NULL, ",");
  31. link_new->from_node = atoi(token);
  32. token = strtok(NULL, ",");
  33. link_new->to_node = atoi(token);
  34. token = strtok(NULL, ",");
  35. link_new->link_length = atof(token);
  36. token = strtok(NULL, ",");
  37. link_new->link_class = atoi(token);
  38. token = strtok(NULL, ",");
  39. link_new->coordinates = geometry_parse(token, ";");
  40. // 将新路段赋值给路段序列,路段序列大小增加
  41. result->sequence[result->sequence_size] = link_new;
  42. result->sequence_size++;
  43. // 路段序列大小达到容量,进行扩容
  44. if( result->sequence_size == result->sequence_capacity )
  45. result = resize_links(result);
  46. // 读取新的一行
  47. gets_return = fgets(buffer, buffer_size, file);
  48. }
  49. // 关闭文件指针
  50. fclose(file);
  51. file = NULL;
  52. return result;
  53. }
  54. link_sequence resize_links(link_sequence origin){
  55. // 初始化新的路段序列指针内存
  56. link_sequence target = (link_sequence) malloc ( sizeof( struct _link_sequence) );
  57. // 初始化新的路段序列的容量、大小和头指针,容量按2倍比例扩容
  58. target->sequence_capacity = 2 * origin->sequence_capacity;
  59. target->sequence_size = origin->sequence_size;
  60. target->sequence = (link*) malloc ( target->sequence_capacity * sizeof( struct _link) );
  61. // 快速初始化头指针内存空间
  62. memset(target->sequence, 0, target->sequence_capacity * sizeof( struct _link));
  63. // 原有路段赋值给新的路段序列
  64. for( int i = 0 ; i < target->sequence_size; i++ )
  65. target->sequence[i] = origin->sequence[i];
  66. // 释放旧的路段序列指针
  67. free(origin);
  68. origin = NULL;
  69. return target;
  70. }

测试主类

头文件main.h

  1. #include "link.h"
  2. #include <stdio.h>
  3. #ifndef STARTREK_MAIN_H
  4. #define STARTREK_MAIN_H
  5. int main();
  6. #endif //STARTREK_MAIN_H

源文件main.c

  1. #include "main.h"
  2. int main() {
  3. // 读入路段序列
  4. link_sequence star_trek = read_link("gis.txt");
  5. return 0;
  6. }

附录A 电子地图数据样例

  1. 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
  2. 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

附录B 浮动车数据样例

  1. 57952495354,20160701120100,116.372966,39.908912,26.00,262
  2. 13381083463,20160701120147,116.387472,39.889589,26.00,266
  3. 13311492120,20160701120144,116.355589,39.993436,10.00,260
  4. 13439610594,20160701120147,116.394988,39.940625,0.00,0
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注