C++获取txt文件内数据的最大最小值进行排序并保存

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

基于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;

}

在这里插入图片描述
在这里插入图片描述

总结

代码有些偏简单,可以优化点很多,这里我尽可能的都在用代码一个一个处理,减少使用一些类库,目的是为了后来改进能方便,效率上很多也可以进一步改进,有问题的地方还希望大家多多指出,便于后续进一步提升。有什么需求也可以评论,有的我随时拿上来给大家分享。

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值