【C/C++学习】数据读入-格式1


这是本人在初学C/C++过程中自编程序,用到了关联容器map、动态内存分配new/delete、文件流的ifstream类和string类及getline、strtok_s函数,刚开始也是看了CSDN许多博文才弄明白,现在分享出来给大家参考。

1. 功能概述

1.1 功能效果

在txt文件中定义好注释和数据后,懒得在程序中再逐一定义变量名了,想直接使用。
功能效果

1.2 使用方法

  1. 输入要求:英文名在前,中文注释在后,中间用空格或制表符隔开,劝你不要用中文作为名字,除非你的文件是用GJB2312编码;
  2. 读入结果:通过定义MapRow类对象,使数据读入内存中,再使用map将数据进行关联。
    使用方法

2. 注意事项

  1. 需要了解map的使用方法,简单的说通过map定义关联容器,保存键/值对,将键“映射”到值上,使用“map名[“键名”]”建立映射关系,“map名.at(“键名”)”使用映射关系;
  2. 便捷是有代价的,当你大量调用map,会花费很长时间;
  3. 通过C风格指针在堆中开辟空间,用析构函数来释放空间,但仍存在未清理的可能性,后续需要改进。

3. 详细代码

MapRow.h

/*
* Auther:	 sanfan66
* Date           | Change
*--------------------------------------------
* 230926         | <record>: None→Version 0.00,Original finished
*                | (describe): MapRow needs input-file with a header in front of the data
*                | (describe): '\t'or' 'to separate the words
*                | !warning!: ~MapRow may not called in some cases
*/
#pragma once
#include <fstream>//ifstream
#include <map>

#include <iostream>//cout
#include <string>//getline
#define EPS 1e-7

using namespace std;//map,string,ifstream

class MapRow {
public:
	MapRow(const char *path, map<string, double>&map_name);
	~MapRow();
	int getNum(ifstream *file, const char *path);
	double getData(ifstream *file, const char *path);

private:
	int nHeader;
	char **header_name;
	double *lines_data;
};

MapRow.cpp

#include "MapRow.h"

MapRow::MapRow(const char *path, map<string, double>&map_name) {
	/* 打开文件、读入行数、读取数据、赋值地址 */
	ifstream file;
	file.open(path, ios::in);
	if (!file.is_open()) {
		cout << path << "无法打开" << endl;
		system("Pause");
		exit(0);
	}

	getNum(&file, path);

	header_name = new char*[nHeader];
	for (int i = 0; i < nHeader; i++) {
		header_name[i] = new char[100];
	}
	lines_data = new double[nHeader] {};

	getData(&file, path);

	for (int i = 0; i < nHeader; i++) {
		map_name[header_name[i]] = lines_data[i];
	}

	file.close();
}

MapRow::~MapRow() {
	/* 清理堆空间,new对应delete,new[]对应delete[] */
	delete[] lines_data;
	lines_data = nullptr;

	for (int i = 0; i < nHeader; i++) {
		delete[] header_name[i];
		header_name[i] = nullptr;
	}
	delete[] header_name;
	header_name = nullptr;
}

int MapRow::getNum(ifstream *file,  const char *path) {
	/* 获取行数 */
	int n = 0, k = 0;
	string one_line;
	while (getline(*file, one_line)) {
		for (unsigned i = 0;i<one_line.size();i++) {
			if (one_line[i] - '0' > -EPS && one_line[i] - '9' < EPS) {
				++n;
				break;
			}
		}		
	}
	nHeader = n;
	if (n==0) {
		cout << path << "无数据" << endl;
		system("Pause");
		exit(0);
	}
	return 0;
}

double MapRow::getData(ifstream *file, const char *path) {
	/* 读取数据 */
	file->clear();
	file->seekg(0, ios::beg);
	int i1 = 0, i2 = 0;
	int indexLines = 0;
	char *one_line_char = nullptr;
	string one_line;
	while (file->peek() != EOF) {
		getline(*file, one_line);
		char *next_word_ptr = nullptr;
		one_line_char = strtok_s(&one_line[0], "\t ", &next_word_ptr);
		
		if (one_line_char != NULL) {
			if (one_line_char[0] - '0' > -EPS && one_line_char[0] - '9' < EPS) {
				lines_data[i2] = atof(one_line_char);
				++i2;
			}
			else {
				if (!((one_line_char[0] - 'a' > -EPS && one_line_char[0] - 'z' < EPS) ||
					(one_line_char[0] - 'A' > -EPS && one_line_char[0] - 'Z' < EPS))) {
					cout << path << "第" << indexLines + 1 << "行表头不是字母" << endl;
					system("Pause");
				}
				strcpy_s(header_name[i1], strlen(one_line_char) + 1, one_line_char);
				++i1;
			}
		}		
		++indexLines;
	}
	if (i1!=i2) {
		cout << path << "表头个数与数据个数不一致" << endl;
		system("Pause");
		exit(0);
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 JSON 数据读入自定义数据结构,你可以使用第三方的 JSON 库,例如 RapidJSON 或者 JSON for Modern C++。这里以 RapidJSON 为例,假设你有以下 JSON 数据: ```json { "name": "John", "age": 30, "address": { "street": "123 Main St", "city": "Anytown", "state": "CA" }, "phoneNumbers": [ { "type": "work", "number": "555-1234" }, { "type": "home", "number": "555-5678" } ] } ``` 你可以定义一个对应的自定义数据结构来存储这些数据: ```c++ #include <string> #include <vector> struct Address { std::string street; std::string city; std::string state; }; struct PhoneNumber { std::string type; std::string number; }; struct Person { std::string name; int age; Address address; std::vector<PhoneNumber> phoneNumbers; }; ``` 然后使用 RapidJSON 的解析器来解析 JSON 数据,并将数据存储到自定义数据结构中: ```c++ #include "rapidjson/document.h" #include "rapidjson/filereadstream.h" #include <cstdio> int main() { // 从文件中读取 JSON 数据 FILE* fp = fopen("data.json", "r"); char readBuffer[65536]; rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer)); // 解析 JSON 数据 rapidjson::Document document; document.ParseStream(is); // 将数据存储到自定义数据结构中 Person person; person.name = document["name"].GetString(); person.age = document["age"].GetInt(); person.address.street = document["address"]["street"].GetString(); person.address.city = document["address"]["city"].GetString(); person.address.state = document["address"]["state"].GetString(); const rapidjson::Value& phoneNumbers = document["phoneNumbers"]; for (rapidjson::SizeType i = 0; i < phoneNumbers.Size(); i++) { PhoneNumber phoneNumber; phoneNumber.type = phoneNumbers[i]["type"].GetString(); phoneNumber.number = phoneNumbers[i]["number"].GetString(); person.phoneNumbers.push_back(phoneNumber); } // 打印自定义数据结构中的数据 printf("Name: %s\n", person.name.c_str()); printf("Age: %d\n", person.age); printf("Address: %s, %s, %s\n", person.address.street.c_str(), person.address.city.c_str(), person.address.state.c_str()); printf("Phone numbers:\n"); for (const auto& phoneNumber : person.phoneNumbers) { printf(" %s: %s\n", phoneNumber.type.c_str(), phoneNumber.number.c_str()); } fclose(fp); return 0; } ``` 这样就可以将 JSON 数据读入自定义数据结构中了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值