提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
基于c++语言对批量的控制点txt文件计算最大与第二大和最小与第二小偏差点
前言
本篇文章主要内容是通过c++代码实现读、写txt文件,其中涉及到平方差计算、数组排序等方法;
提示:以下是本篇文章正文内容,下面案例可供参考
一、实现c++对txt内数据进行计算、排序、保留最大最小值?
实现逻辑如下:
1、读取txt
2、计算数值对平方根
3、获取偏差最小的两个点
4、获取偏差最大的两个点
5、数组排序
6、读取txt内指定行数据
7、写入txt
二、实现步骤
1.创建新项目
1.1、选择已安装好的Visual Studio 2019:
1.2、选择新项目,点击下一步进行创建:
1.3、新建主函数main,点源文件->添加->新建项:
选择c++文件(.cpp)名称输入main,新建主函数main,点击添加:
2.环境配置:
2.1、到这里新项目就建立完成,接下来进行环境配置:
2.2、环境引入gdal类库(由于我这里只用到gdal类库,如有其他功能需求可以引入其他类库,以此类推)
2.3、拷贝gdal类库的dll
到这里所有的环境和项目都已准备和引入完成,接下来开始写代码。
3.功能实现
3.1、先输入"helow world!"测试一下程序是否可以正常运行:
如下图显示即为可正常执行!
3.2、选择输入数据,如下图所示,这里主要对每一行的两对经纬度坐标进行求均方差,比较每组数据的大小,进行排序,保留最大、第二大、最小、第二小四组数据,其他数据删除:
上代码:
#include
#include
#include
#include <stdio.h>
#include <stdlib.h>
#include “malloc.h”
#include
#include
#include
#include <io.h>
#include <direct.h>
#include <sys/stat.h>
#define ACCESS(fileName, accessMode) _access(fileName, accessMode)
using namespace std;
/* 获取文件行数*/
int GetFileRows(const char* file);
void find_second_max(double* a, size_t n, double* first_second_max, int* max_id);
void find_second_min(double* a, size_t n, double* first_second_min, int* min_id);
int CountLines(char* filename);
string ReadLine(string filename, int line);
//判断路径是否存在
bool IsExist(const char* src);
int main()
{
string txt_path = “”;
txt_path = “D:\data\1.txt”;
//对控制点文件解读,超过四个控制点以上保留两个偏差最大点和两个偏差最小点
int num_points = GetFileRows(txt_path.c_str());
double mapx_test = 0.0;
double mapy_test = 0.0;
double mapx_basemaptest = 0.0;
double mapy_basemaptest = 0.0;
double* square_root = new double[num_points];
double* first_secend_max = new double[2];
/int max_id_1 = 0;
int max_id_2 = 0;/
double* first_secend_min = new double[2];
/int min_id_1 = 0;
int min_id_2 = 0;/
int* max_id = new int[2];
int* min_id = new int[2];
double min1 = 0.0;
double min2 = 0.0;
int min_id_1 = 0;
int min_id_2 = 0;
vector<int> num;
if (num_points > 4)
{
FILE* fp;
if (fopen_s(&fp, txt_path.c_str(), "r") != 0)
{
printf("无法打开%s控制点文件!\n", txt_path.c_str());
}
else
{
for (int k = 0;k < num_points;k++)
{
/*fscanf_s(fp, "%lf,%lf,%lf,%lf", mapx_test, mapy_test, mapx_basemaptest, mapy_basemaptest);*/
fscanf_s(fp, "%lf,%lf,%lf,%lf", &mapx_test, &mapy_test, &mapx_basemaptest, &mapy_basemaptest);
double PF = 0.0;
PF = pow((mapx_test - mapx_basemaptest), 2) + pow((mapy_test - mapy_basemaptest), 2);
// 求n的平方根
square_root[k] = sqrt(PF);
}
//获取偏差最小的两个点
find_second_min(square_root, num_points, first_secend_min, min_id);
//获取偏差最大的两个点
find_second_max(square_root, num_points, first_secend_max, max_id);
cout << "偏差最大的点: " << first_secend_max[0] << ":" << max_id[0] << endl;
cout << "偏差第二大的点: " << first_secend_max[1] << ":" << max_id[1] << endl;
cout << "偏差最小的点: " << first_secend_min[0] << ":" << min_id[0] << endl;
cout << "偏差第二小的点: " << first_secend_min[1] << ":" << min_id[1] << endl;
int sort_s[4] = { max_id[0] , max_id[1] ,min_id[0],min_id[1] };
//排序
sort(sort_s, sort_s + 4, greater<int>());
num.push_back(sort_s[3]);
num.push_back(sort_s[2]);
num.push_back(sort_s[1]);
num.push_back(sort_s[0]);
}
fclose(fp);
保留四个点
//deleteLine(txt_path, num_points, num);
vector<string> ReadLine_s;
cout << num.size() << endl;
for (int k = 0; k < num.size(); k++)
{
string ReadLine_ss = "";
ReadLine_ss = ReadLine(txt_path, num[k]);
ReadLine_s.push_back(ReadLine_ss.c_str());
}
/*cout << ReadLine_s[0] << endl;
cout << ReadLine_s[1] << endl;
cout << ReadLine_s[2] << endl;
cout << ReadLine_s[3] << endl;*/
num.clear();
num.shrink_to_fit();
//写入
if (IsExist(txt_path.c_str()) == true)
{
remove(txt_path.c_str());
}
FILE* fp2;
fopen_s(&fp2, txt_path.c_str(), "w");
if (fp2 == NULL)
{
printf("Cann't create or open feature points file : %s\n", txt_path.c_str());
fclose(fp2);
ReadLine_s.clear();
ReadLine_s.shrink_to_fit();
return false;
}
else
{
for (int n = 0;n < ReadLine_s.size();n++)
{
fprintf(fp2, "%s\n", ReadLine_s[n].c_str());
}
}
fclose(fp2);
ReadLine_s.clear();
ReadLine_s.shrink_to_fit();
}
return 0;
}
//判断路径是否存在
bool IsExist(const char* src)
{
if (ACCESS(src, 0) == 0) // != -1
{
return true;
}
else
{
return false;
}
}
int GetFileRows(const char* file)
{
char sline[512];
FILE* fp;
int rows = 0;
if (fopen_s(&fp, file, "r") != 0)//fopen修改为fopen_s
{
printf("无法打开此文件!\n");
return 0;
}
while (fgets(sline, 512, fp) != NULL)
rows++;
fclose(fp);
return rows;
}
void find_second_max(double* a, size_t n, double* first_second_max, int* max_id) //数组a,长度n>1
{
/用a[0]和a[1]来初始化max和second_max/
double second_max = a[0];
double max = a[0];
if (a[1] > a[0]) //第二个数大于第一个数
{
max = a[1]; //max = 第二个数 2
}
else
{
second_max = a[1]; //second_max = 第二个数 1
}
max_id[0] = 0;
max_id[0] = 0;
for (size_t i = 2; i < n; ++i)
{
if (a[i] > max)
{
max = a[i];//获取最大的数
max_id[0] = i;
/*cout << "####" << endl;
cout << max_id[0] << endl;*/
}
}
for (size_t i = 2; i < n; ++i)
{
if (max_id[0] == i)
{
}
else if (a[i] > second_max)
{
second_max = a[i];//获取第二大的数
max_id[1] = i;
/*cout << max_id_2 << endl;
cout << "first_second_max[1]:" << second_max << endl;*/
}
}
/*if (max_id[0] != 0)
{*/
max_id[0] = max_id[0] + 1;
/*}*/
/*if(max_id[1] != 0)
{*/
max_id[1] = max_id[1] + 1;
//}
first_second_max[0] = max;
first_second_max[1] = second_max;
}
void find_second_min(double* a, size_t n, double* first_second_min, int* min_id) //数组a,长度n>1
{
/用a[0]和a[1]来初始化max和second_max/
double second_min = a[0];
double min = a[0];
if (a[1] < a[0]) //第二个数小于第一个数
{
min = a[1]; //min = 第二个数 2
}
else
{
second_min = a[1]; //second_min = 第二个数 2
}
min_id[0] = 0;
min_id[1] = 0;
for (size_t i = 2; i < n; ++i)
{
if (a[i] < min)
{
min = a[i];//获取最大的数
min_id[0] = i;
/*cout << max_id_1 <<endl;
cout << "first_second_max[0]:" << max << endl;*/
}
//if (a[i] < second_min && min < second_min)
//{
// second_min = a[i];//获取第二大的数
// min_id[1] = i;
// /*cout << max_id_2 << endl;
// cout << "first_second_max[1]:" << second_max << endl;*/
//}
}
for (size_t i = 2; i < n; ++i)
{
if (min_id[0] == i)
{
}
else
{
if (a[i] < second_min)
{
second_min = a[i];//获取第二大的数
min_id[1] = i;
/*cout << max_id_2 << endl;
cout << "first_second_max[1]:" << second_max << endl;*/
}
}
}
first_second_min[0] = min;
first_second_min[1] = second_min;
/*if (min_id[0] != 0)
{*/
min_id[0] = min_id[0] + 1;
//}
/*if (min_id[1] != 0)
{*/
min_id[1] = min_id[1] + 1;
//}
}
int CountLines(char* filename)
{
ifstream ReadFile;
int n = 0;
string tmp = “”;
ReadFile.open(filename, ios::in);//ios::in 表示以只读的方式读取文件
if (ReadFile.fail())//文件打开失败:返回0
{
return 0;
}
else//文件存在
{
while (getline(ReadFile, tmp, ‘\n’))
{
n++;
}
ReadFile.close();
return n;
}
}
//读取指定行
string ReadLine(string filename, int line)
{
char ch[1024];
strcpy_s(ch, filename.c_str());
int lines = 0;
int i = 0;
string temp = "";
fstream file;
file.open(filename.c_str());
lines = CountLines(ch);
if (line <= 0)
{
return "Error 1: 行数错误,不能为0或负数。";
}
if (file.fail())
{
return "Error 2: 文件不存在。";
}
if (line > lines)
{
cout << "行数" << endl;
cout << line << endl;
cout << lines << endl;
return "Error 3: 行数超出文件长度。";
}
while (getline(file, temp) && i < line - 1)
{
i++;
}
file.close();
return temp;
}
总结
代码有些偏简单,可以优化点很多,这里我尽可能的都在用代码一个一个处理,减少使用一些类库,目的是为了后来改进能方便,效率上很多也可以进一步改进,有问题的地方还希望大家多多指出,便于后续进一步提升。有什么需求也可以评论,有的我随时拿上来给大家分享。