最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++讀寫(CSV,Yaml,二進(jìn)制)文件的方法詳解

 更新時(shí)間:2022年05月06日 08:29:59   作者:求則得之,舍則失之  
為了處理文件,我們可以利用fstream庫(kù)。在這個(gè)庫(kù)里面有三種數(shù)據(jù)類型:ofstream,ifstream,fstream。本文將利用這個(gè)庫(kù)實(shí)現(xiàn)不同文件的讀寫操作,需要的可以參考一下

介紹

為了處理文件,首先,導(dǎo)入 fstream 庫(kù)。 在這個(gè)庫(kù)里面有三種數(shù)據(jù)類型:

  • ofstream - 用于寫入文件
  • ifstream - 用于從文件中讀取
  • fstream - 用于讀取和寫入

為了打開(kāi)文件,我們使用 open() 函數(shù)。 該函數(shù)接收兩個(gè)參數(shù):文件名和文件打開(kāi)方式。

可以打開(kāi)文件的模式如下:

  • ios::in - 打開(kāi)要讀取的文件(ifstream 的默認(rèn)值)
  • ios::out - 打開(kāi)要寫入的文件(ofstream 的默認(rèn)值)
  • ios::binary - 以二進(jìn)制模式打開(kāi)文件
  • ios::app- 打開(kāi)文件以在末尾附加新信息
  • ios::ate - 打開(kāi)并將控件移動(dòng)到文件末尾
  • ios::trunc - 刪除現(xiàn)有文件中的數(shù)據(jù)
  • ios::nocreate - 僅在文件已存在時(shí)打開(kāi)文件
  • ios::noreplace - 僅在文件不存在時(shí)打開(kāi)文件

我們還可以使用符號(hào) | 組合不同的模式 例如: myFile.open(“saldinaFile.txt”, ios::out | ios::in); 在此示例中,我們打開(kāi) saldinaFile.txt 進(jìn)行寫入和讀取。

1.讀寫txt文件

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
	fstream myFile;
	myFile.open("saldina.txt", ios::out);  // write,清空再寫入
	if (myFile.is_open())
	{
		myFile << "Hello\n";
		myFile << "This is second line\n";
		myFile.close();
	}
	myFile.open("saldina.txt", ios::app);  // append,追加
	if (myFile.is_open())
	{
		myFile << "Hello2\n";
		myFile << "This is third line\n";
		myFile.close();
	}
	myFile.open("saldina.txt", ios::in);  // read,讀
	if (myFile.is_open())
	{
		string line;
		while (getline(myFile, line))
		{
			cout << line << endl;
		}
		myFile.close();
	}
}


2.C++讀寫CSV文件

據(jù)我所知,C++ STL 中沒(méi)有內(nèi)置 CSV 讀取器/寫入器。這不是對(duì) C++ 的打擊。它只是一種低級(jí)語(yǔ)言。如果我們想用 C++ 讀寫 CSV 文件,我們將不得不處理文件 I/O、數(shù)據(jù)類型和一些關(guān)于如何讀取、解析和寫入數(shù)據(jù)的低級(jí)邏輯。對(duì)我來(lái)說(shuō),這是構(gòu)建和測(cè)試更多有趣程序(如機(jī)器學(xué)習(xí)模型)的必要步驟。

2.1 寫入CSV

這里,ofstream是一個(gè)“輸出文件流”。由于它派生自ostream,我們可以像對(duì)待cout一樣對(duì)待它(它也是派生自ostream)。執(zhí)行這個(gè)程序的結(jié)果是,我們?cè)诳蓤?zhí)行文件所在的目錄中得到了一個(gè)名為ones.csv的文件。讓我們將它封裝到write_csv()函數(shù)中。

#include <string>
#include <fstream>
#include <vector>

void write_csv(std::string filename, std::string colname, std::vector<int> vals){
    // Make a CSV file with one column of integer values
    // filename - the name of the file
    // colname - the name of the one and only column
    // vals - an integer vector of values
    
    // Create an output filestream object
    std::ofstream myFile(filename);
    
    // Send the column name to the stream
    myFile << colname << "\n";
    
    // Send data to the stream
    for(int i = 0; i < vals.size(); ++i)
    {
        myFile << vals.at(i) << "\n";
    }
    
    // Close the file
    myFile.close();
}

int main() {
    // Make a vector of length 100 filled with 1s
    std::vector<int> vec(100, 1);
    
    // Write the vector to CSV
    write_csv("ones.csv", "Col1", vec);
    
    return 0;
}

現(xiàn)在我們可以使用 write_csv() 輕松地將整數(shù)向量寫入 CSV 文件。讓我們對(duì)此進(jìn)行擴(kuò)展以支持多個(gè)整數(shù)向量和相應(yīng)的列名。

#include <string>
#include <fstream>
#include <vector>
#include <utility> // std::pair

void write_csv(std::string filename, std::vector<std::pair<std::string, std::vector<int>>> dataset){
    // Make a CSV file with one or more columns of integer values
    // Each column of data is represented by the pair <column name, column data>
    //   as std::pair<std::string, std::vector<int>>
    // The dataset is represented as a vector of these columns
    // Note that all columns should be the same size
    
    // Create an output filestream object
    std::ofstream myFile(filename);
    
    // Send column names to the stream
    for(int j = 0; j < dataset.size(); ++j)
    {
        myFile << dataset.at(j).first;
        if(j != dataset.size() - 1) myFile << ","; // No comma at end of line
    }
    myFile << "\n";
    
    // Send data to the stream
    for(int i = 0; i < dataset.at(0).second.size(); ++i)
    {
        for(int j = 0; j < dataset.size(); ++j)
        {
            myFile << dataset.at(j).second.at(i);
            if(j != dataset.size() - 1) myFile << ","; // No comma at end of line
        }
        myFile << "\n";
    }
    
    // Close the file
    myFile.close();
}

int main() {
    // Make three vectors, each of length 100 filled with 1s, 2s, and 3s
    std::vector<int> vec1(100, 1);
    std::vector<int> vec2(100, 2);
    std::vector<int> vec3(100, 3);
    
    // Wrap into a vector
    std::vector<std::pair<std::string, std::vector<int>>> vals = {{"One", vec1}, {"Two", vec2}, {"Three", vec3}};
    
    // Write the vector to CSV
    write_csv("three_cols.csv", vals);
    
    return 0;
}

在這里,我們將每列數(shù)據(jù)表示為 <column name, column values> 的 std::pair,并將整個(gè)數(shù)據(jù)集表示為此類列的 std::vector?,F(xiàn)在我們可以將可變數(shù)量的整數(shù)列寫入 CSV 文件。

2.2 讀取CSV文件(1)

現(xiàn)在我們已經(jīng)編寫了一些 CSV 文件,讓我們嘗試讀取它們。現(xiàn)在讓我們假設(shè)我們的文件包含整數(shù)數(shù)據(jù)和頂部的一行列名。

#include <string>
#include <fstream>
#include <vector>
#include <utility> // std::pair
#include <stdexcept> // std::runtime_error
#include <sstream> // std::stringstream

std::vector<std::pair<std::string, std::vector<int>>> read_csv(std::string filename){
    // Reads a CSV file into a vector of <string, vector<int>> pairs where
    // each pair represents <column name, column values>

    // Create a vector of <string, int vector> pairs to store the result
    std::vector<std::pair<std::string, std::vector<int>>> result;

    // Create an input filestream
    std::ifstream myFile(filename);

    // Make sure the file is open
    if(!myFile.is_open()) throw std::runtime_error("Could not open file");

    // Helper vars
    std::string line, colname;
    int val;

    // Read the column names
    if(myFile.good())
    {
        // Extract the first line in the file
        std::getline(myFile, line);

        // Create a stringstream from line
        std::stringstream ss(line);

        // Extract each column name
        while(std::getline(ss, colname, ',')){
            
            // Initialize and add <colname, int vector> pairs to result
            result.push_back({colname, std::vector<int> {}});
        }
    }

    // Read data, line by line
    while(std::getline(myFile, line))
    {
        // Create a stringstream of the current line
        std::stringstream ss(line);
        
        // Keep track of the current column index
        int colIdx = 0;
        
        // Extract each integer
        while(ss >> val){
            
            // Add the current integer to the 'colIdx' column's values vector
            result.at(colIdx).second.push_back(val);
            
            // If the next token is a comma, ignore it and move on
            if(ss.peek() == ',') ss.ignore();
            
            // Increment the column index
            colIdx++;
        }
    }

    // Close file
    myFile.close();

    return result;
}

int main() {
    // Read three_cols.csv and ones.csv
    std::vector<std::pair<std::string, std::vector<int>>> three_cols = read_csv("three_cols.csv");
    std::vector<std::pair<std::string, std::vector<int>>> ones = read_csv("ones.csv");

    // Write to another file to check that this was successful
    write_csv("three_cols_copy.csv", three_cols);
    write_csv("ones_copy.csv", ones);
    
    return 0;
}

該程序讀取我們之前創(chuàng)建的 CSV 文件并將每個(gè)數(shù)據(jù)集寫入一個(gè)新文件,本質(zhì)上是創(chuàng)建原始文件的副本。

2.3 讀取CSV文件(2)

示例CSV文件如下所示。

在這個(gè)文件中,每行中的每個(gè)值都由逗號(hào)分隔。第一行表示列名,分別為姓名、性別和年齡。在每一行之后,都有一個(gè)換行符,該換行符存儲(chǔ)在內(nèi)部,在文件中不可見(jiàn)。文件中的每一行表示一個(gè)不同的記錄,而每個(gè)逗號(hào)分隔的值表示記錄的一個(gè)字段。

讀取 CSV 文件本質(zhì)上類似于讀取 C++ 中的所有其他文件。不同之處在于從行中提取值的方式。要讀取 CSV 文件,

  • 我們將使用C++ 庫(kù)的fstream 或 ifstream打開(kāi)文件。然后,我們將使用getline()方法逐行讀取文件,因?yàn)槊恳恍卸家該Q行符結(jié)尾。
  • 該getline()方法將文件流作為其第一個(gè)輸入?yún)?shù),將一個(gè)字符串變量作為其第二個(gè)參數(shù)。執(zhí)行后,它將文件流的下一行存儲(chǔ)在字符串變量中。它還接受一個(gè)可選參數(shù)delimitor。如果我們將分隔符作為輸入?yún)?shù)傳遞,它會(huì)讀取文件直到找到分隔符。否則,它會(huì)讀取文件直到找到換行符。
  • 提取一行后,我們將使用stringstream提取該行中用逗號(hào)分隔的單詞。顧名思義,stringstream將字符串轉(zhuǎn)換為類似文件流的對(duì)象。
  • 在這里,我們將使用getline()方法來(lái)讀取由stringstream創(chuàng)建的字符串流。使用getline()時(shí),除了字符串流和名為 word 的字符串變量外,我們還將,作為第三個(gè)參數(shù)傳遞給getline()函數(shù)。通過(guò)這種方式,getline()函數(shù)只讀取數(shù)據(jù),直到一行中的下一個(gè)逗號(hào)符號(hào)。
  • 我們將每個(gè)單詞存儲(chǔ)在一個(gè)名為row的向量中,每個(gè)單詞row存儲(chǔ)在一個(gè)名為content的二維向量中。執(zhí)行整個(gè)程序后,我們得到一個(gè)二維向量,其中每一行代表 CSV 文件中的一條記錄,每一行的每一列代表其中的數(shù)據(jù)。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
 
using namespace std;
 
int main()
{
	string fname;
	cout<<"Enter the file name: ";
	cin>>fname;
 
	vector<vector<string>> content;
	vector<string> row;
	string line, word;
 
	fstream file (fname, ios::in);
	if(file.is_open())
	{
		while(getline(file, line))
		{
			row.clear();
 
			stringstream str(line);
 
			while(getline(str, word, ','))
				row.push_back(word);
			content.push_back(row);
		}
	}
	else
		cout<<"Could not open the file\n";
 
	for(int i=0;i<content.size();i++)
	{
		for(int j=0;j<content[i].size();j++)
		{
			cout<<content[i][j]<<" ";
		}
		cout<<"\n";
	}
 
	return 0;
}

上述代碼的輸出如下所示。我們使用上面給出的 CSV 文件作為程序的輸入。

2.4 用c++讀寫二進(jìn)制文件(1)

/**
 * @description - Read any ASCII,BINARY or HEX file.
 * @param - Source file name and file type.
 * @return - Returns data in tuple format,use std::get<TUPLE_ID>(TUPLE_OBJ) to get data.
 */
/*Including STD-C++ libraries*/
#include <iostream> /*For basic I/O.*/
#include <fstream> /*For basic I/O.*/
#include <sstream> /*For basic I/O.*/
#include <vector> /*For STL vector.*/
#include <tuple>  /*For packing multi data.*/

using std::string;

#define BINARY_FILE 0
#define ASCII_FILE 1
#define HEX_FILE 2
std::tuple<std::vector<uint8_t>, string, string> ReadFile(string, int);
bool WriteFile(string file_name, string, int);

/*
Example of binary file:
	auto file_type = ReadFile("user_data.dat", BINARY_FILE);
	auto file_data = std::get<BINARY_FILE>(file_type);

Example of ASCII file:
	auto file_type = ReadFile("my_file.txt", ASCII_FILE);
	auto file_data = std::get<ASCII_FILE>(file_type);
*/

std::tuple<std::vector<uint8_t>, string, string> ReadFile(string file_name, int file_type)
{
	/*Buffers to store output data from file.*/
	string str_buf, hex_buf;
	std::vector<uint8_t> vec_buf;

	try {
		if (file_type == BINARY_FILE) {

			/*Open the stream in binary mode.*/
			std::ifstream bin_file(file_name, std::ios::binary);

			if (bin_file.good()) {
				/*Read Binary data using streambuffer iterators.*/
				std::vector<uint8_t> v_buf((std::istreambuf_iterator<char>(bin_file)), (std::istreambuf_iterator<char>()));
				vec_buf = v_buf;
				bin_file.close();
			}

			else {
				throw std::exception();
			}

		}

		else if (file_type == ASCII_FILE) {

			/*Open the stream in default mode.*/
			std::ifstream ascii_file(file_name);
			string ascii_data;

			if (ascii_file.good()) {
				/*Read ASCII data using getline*/
				while (getline(ascii_file, ascii_data))
					str_buf += ascii_data + "\n";

				ascii_file.close();
			}
			else {
				throw std::exception();
			}
		}

		else if (file_type == HEX_FILE) {

			/*Open the stream in default mode.*/
			std::ifstream hex_file(file_name);

			if (hex_file.good()) {
				/*Read Hex data using streambuffer iterators.*/
				std::vector<char> h_buf((std::istreambuf_iterator<char>(hex_file)), (std::istreambuf_iterator<char>()));
				string hex_str_buf(h_buf.begin(), h_buf.end());
				hex_buf = hex_str_buf;

				hex_file.close();
			}
			else {
				throw std::exception();
			}
		}

	}

	catch (std::exception const& ex) {
		string ex_str = "Error: " + file_name + ": No such file or directory";
		throw std::exception(ex_str.c_str());
	}

	auto tuple_data = make_tuple(vec_buf, str_buf, hex_buf);
	return tuple_data;
}

/**
 * @description - Write data to any ASCII,BINARY or HEX file.
 * @param - Source file name, file data and file type.
 * @return - Returns true on successfully written data otherwise returns false.
 */

bool WriteFile(string file_name, string file_data, int file_type)
{
	bool write_status = false;
	std::ofstream out_stream(file_name, (file_type == ASCII_FILE) ? std::ios::out : (file_type == BINARY_FILE || file_type == HEX_FILE) ? std::ios::binary : std::ios::out);

	if (out_stream.is_open()) {
		if (file_type == ASCII_FILE) {
			out_stream << file_data;
			write_status = true;
		}

		else if (file_type == BINARY_FILE) {
			out_stream << file_data;
			write_status = true;
		}

		else if (file_type == HEX_FILE) {
			int bin_data;
			std::stringstream ss;
			ss << std::hex << file_data;

			while (ss >> bin_data)
				out_stream.write(reinterpret_cast<const char*>(&bin_data), sizeof(char));

			write_status = true;
		}
		out_stream.close();
	}
	else {
		string ex_str = "Error: couldn't open " + file_name + " for output";
		throw std::exception(ex_str.c_str());
	}
	return write_status;
}

2.5 用c++讀寫二進(jìn)制文件(2)

1.寫

用C++寫二進(jìn)制文件,請(qǐng)使用write方法,它用于在給定流上寫入給定數(shù)量的字節(jié),從put指針的位置開(kāi)始。如果put指針當(dāng)前位于文件的末尾,則擴(kuò)展文件。如果該指針指向文件的中間,則文件中的字符將被新數(shù)據(jù)覆蓋。如果在寫入文件期間發(fā)生了任何錯(cuò)誤,則將流置于錯(cuò)誤狀態(tài)。

寫方法的語(yǔ)法:ostream& write(const char*, int);

2.讀

要在c++中讀取二進(jìn)制文件,請(qǐng)使用read方法。它從給定的流中提取給定數(shù)量的字節(jié),并將它們放入由第一個(gè)參數(shù)指向的內(nèi)存中。如果在讀取文件期間發(fā)生任何錯(cuò)誤,則將流置于錯(cuò)誤狀態(tài),隨后所有的讀取操作都將失敗。

gcount()可用于統(tǒng)計(jì)已經(jīng)讀取的字符數(shù)。然后可以使用clear()將流重置為可用狀態(tài)。

讀方法的語(yǔ)法:ifstream& write(const char*, int);

3.偽代碼

Begin
   Create a structure Student to declare variables.
   Open binary file to write.
   Check if any error occurs in file opening.
   Initialize the variables with data.
   If file open successfully, write the binary data using write method.
      Close the file for writing.
   Open the binary file to read.
   Check if any error occurs in file opening.
   If file open successfully, read the binary data file using read method.
      Close the file for reading.
   Check if any error occurs.
   Print the data.
End.

4.示例代碼

#include<iostream>
#include<fstream>
using namespace std;
struct Student {
   int roll_no;
   string name;
};
int main() {
   ofstream wf("student.dat", ios::out | ios::binary);
   if(!wf) {
      cout << "Cannot open file!" << endl;
      return 1;
   }
   Student wstu[3];
   wstu[0].roll_no = 1;
   wstu[0].name = "Ram";
   wstu[1].roll_no = 2;
   wstu[1].name = "Shyam";
   wstu[2].roll_no = 3;
   wstu[2].name = "Madhu";
   for(int i = 0; i < 3; i++)
      wf.write((char *) &wstu[i], sizeof(Student));
   wf.close();
   if(!wf.good()) {
      cout << "Error occurred at writing time!" << endl;
      return 1;
   }
   ifstream rf("student.dat", ios::out | ios::binary);
   if(!rf) {
      cout << "Cannot open file!" << endl;
      return 1;
   }
   Student rstu[3];
   for(int i = 0; i < 3; i++)
      rf.read((char *) &rstu[i], sizeof(Student));
   rf.close();
   if(!rf.good()) {
      cout << "Error occurred at reading time!" << endl;
      return 1;
   }
   cout<<"Student's Details:"<<endl;
   for(int i=0; i < 3; i++) {
      cout << "Roll No: " << wstu[i].roll_no << endl;
      cout << "Name: " << wstu[i].name << endl;
      cout << endl;
   }
   return 0;
}

輸出:

Student’s Details:
Roll No: 1
Name: Ram
Roll No: 2
Name: Shyam
Roll No: 3
Name: Madhu

2.6 用c++讀寫二進(jìn)制文件(3)

1.問(wèn)題描述

我使用以下代碼創(chuàng)建一個(gè)簡(jiǎn)單的二進(jìn)制文件。

ofstream outfile("binary.txt", ofstream::binary);
string text = "Hello cplusplus forum!";
outfile.write((char*)&text, text.size());
outfile.close();

當(dāng)我打開(kāi)此文件時(shí),它是二進(jìn)制文件,但每當(dāng)我嘗試使用此代碼將此文件讀回程序時(shí):

char* buffer = (char*)malloc(sizeof(string));
ifstream infile("binary.txt", ifstream::binary);
infile.read(buffer, sizeof(string));
string* elem = (string*)buffer;
cout << *elem << '\n';
infile.close();

程序和Visual Studio崩潰了。

2.解答

第一部分有幾個(gè)問(wèn)題:

ofstream outfile("binary.txt", ofstream::binary);
string text = "Hello cplusplus forum!";
outfile.write((char*)&text, text.size());
outfile.close();

該代碼可能會(huì)毫無(wú)問(wèn)題地運(yùn)行。但是文件 binary.txt 中包含什么?對(duì)于這類工作,十六進(jìn)制編輯器很有用。在 Windows 上,您可以嘗試 Hxdhttps://mh-nexus.de/en/hxd/

在我的系統(tǒng)上看到的是這樣的:TA>.$ÀÂw..>.LXH.èUH.@? 這很沒(méi)有意義。這是因?yàn)樽址畬?duì)象可能不包含字符串的文本,而是包含指向堆上保存的字符串的指針,以及可能的一些其他信息。

第一步是編寫字符串本身的實(shí)際文本內(nèi)容。

可以通過(guò)替換第3行來(lái)實(shí)現(xiàn):outfile.write((char*)&text, text.size());改為outfile.write( text.c_str(), text.size());

現(xiàn)在,如果您再看一下文件的內(nèi)容,它應(yīng)該更有意義。

但這仍然留下一個(gè)問(wèn)題。你將如何讀回它?如果這就是文件包含的所有內(nèi)容,這很容易,只需閱讀到文件末尾即可。但是,如果您只想讀取原始字符串,不多也不少怎么辦?

那么你可以先在文件中存儲(chǔ)大小。像這樣:

unsigned int size = text.size();
outfile.write(reinterpret_cast<char *>(&size), sizeof(size)  );

要讀取文件,請(qǐng)按相反的步驟執(zhí)行。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
    
int main()
{   

    string text = "Hello cplusplus forum!";

    ofstream outfile("binary.txt", ofstream::binary);
    unsigned int size = text.size();                                 // get the size
    outfile.write(reinterpret_cast<char *>(&size), sizeof(size)  );  // write it to the file
    outfile.write( text.c_str(), text.size() );                      // write the actual text
    outfile.close();


    //----------------------------------------

    ifstream infile("binary.txt", ifstream::binary);
    
    // read the size
    size = 0;        
    infile.read(reinterpret_cast<char *>(&size), sizeof(size)  );
    
    // Allocate a string, make it large enough to hold the input
    string buffer;
    buffer.resize(size);
    
    // read the text into the string
    infile.read(&buffer[0],  buffer.size() );
    infile.close();    
    
    cout << "buffer = \n" << buffer << '\n';
    
}

3.C++讀寫Yaml文件

它的基本語(yǔ)法規(guī)則如下:

  • 大小寫敏感
  • 使用縮進(jìn)表示層級(jí)關(guān)系
  • 縮進(jìn)時(shí)不允許使用Tab鍵,只允許使用空格。
  • 縮進(jìn)的空格數(shù)目不重要,只要相同層級(jí)的元素左側(cè)對(duì)齊即可

YAML支持的數(shù)據(jù)結(jié)構(gòu)有三種。

  • 對(duì)象:鍵值對(duì)的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 數(shù)組:一組按次序排列的值,又稱為序列(sequence) / 列表(list)
  • 純量(scalars):?jiǎn)蝹€(gè)的、不可再分的值

一般常用yaml-cpp和OpenCV進(jìn)行解析

相比yaml-cpp,OpenCV的優(yōu)點(diǎn)是可以在YAML文件中存儲(chǔ)矩陣,讀出來(lái)就是cv::Mat格式;缺點(diǎn)是OpenCV要求YAML文件有一個(gè)特殊的頭,與標(biāo)準(zhǔn)的YAML文件并不兼容?;蛘咭部梢岳斫鉃镺penCV定義了一種新的YAML格式。

# 表示注釋,從這個(gè)字符一直到行尾,都會(huì)被解析器忽略。

3.1安裝yaml-cpp

https://github.com/jbeder/yaml-cpp/

編譯環(huán)境

  • Windows10
  • VS2019
  • cmake-3.19.8-win64-x64

yaml-cpp的編譯

將下載好的yaml-cpp-master.zip進(jìn)行解壓,在源碼目錄下創(chuàng)建一個(gè)build文件夾并進(jìn)入這個(gè)文件夾

mkdir build
cd build
cmake ..

接著將會(huì)看到在build目錄下有一個(gè)名為YAM_-CPP.sln的文件,用VS打開(kāi)它

對(duì)ALL_BUILD生成解決方案,成功生成后,會(huì)在build/Debug目錄下得到y(tǒng)aml-cppd.lib文件

3.2 yaml文件的解析(1)

1)config.yaml配置文件

custom_db:
    db_domain: 10.0.0.8
    db_username: root
    db_passwd: my_passwd
    db_schema: test

redis:
    redis_domain: 10.0.0.10
    redis_passwd: 123456

hello:
    num_config: [1141studio]
    name_config: [powered, by, 1141studio]

2)config_test.cpp

#include <iostream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include "yaml-cpp/yaml.h"
#include <vector>
const std::string DB_CONF = "config.yaml";
int main(int argc, char * argv[]) {
    /*----------------------------------- test yaml ----------------------------------------*/
    printf("hello world\n");
    std::cout << "this code is only for test yaml" << std::endl;

    /* Node conf. */
    YAML::Node conf = YAML::LoadFile(DB_CONF);
    
    /*----------------------------------- display db_config ----------------------------------------*/
    std::cout << "Database:"<< std::endl;
    std::cout << "domain:  " << conf["custom_db"]["db_domain"].as<std::string>() << std::endl;
    std::cout << "username:" << conf["custom_db"]["db_username"].as<std::string>() << std::endl;
    std::cout << "passwd:  " << conf["custom_db"]["db_passwd"].as<std::string>() << std::endl;
    std::cout << "schema:  " << conf["custom_db"]["db_schema"].as<std::string>() << std::endl;

    /*----------------------------------- display redis ----------------------------------------*/
    std::cout << "Redis" << std::endl;
    std::cout << "redis_domain: " << conf["redis"]["redis_domain"].as<std::string>() << std::endl;
    std::cout << "redis_passwd: " << conf["redis"]["redis_passwd"].as<std::string>() << std::endl;
    
    /*----------------------------------- display hello ----------------------------------------*/
    std::cout << "HelloServer" << std::endl;
    
    /* vector of name string. */
    std::vector<std::string> name_vec = conf["hello"]["num_config"].as<std::vector<std::string> >();
    if(!name_vec.empty())
      std::cout << name_vec[0] << std::endl;
    return 0;
}

3)CmakeLists.txt配置情況如下

cmake_minimum_required(VERSION 3.5.1)
project(nanodet-mnn)
SET(CMAKE_BUILD_TYPE "Release")

SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/)

# yaml-cpp的包含目錄
include_directories("/gzy_mnt/YAML_X86/include")
file(GLOB SOURCE_FILES *.cpp)
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})

target_link_libraries (
        ${CMAKE_PROJECT_NAME}   
        pthread
        /gzy_mnt/YAML_X86/lib/libyaml-cpp.so
)

3.3 yaml文件的解析(2)

config.yaml配置文件

name: frank
sex: male
age: 18
 
skills: 
    c++: 1
    java: 1
    android: 1
    python: 1

config_demo.cpp

#include <iostream>
#include "yaml-cpp/yaml.h"
#include <fstream>
 
using namespace std;
 
int main(int argc,char** argv)
{
    YAML::Node config;
    try{
         config = YAML::LoadFile("../config.yaml");
    }catch(YAML::BadFile &e){
        std::cout<<"read error!"<<std::endl;
        return -1;
    }
    
    cout << "Node type " << config.Type() << endl;
    cout << "skills type " << config["skills"].Type() << endl;
 
    //可以用string類型作為下表,讀取參數(shù)
    string age = "age";
    cout << "age when string is label:" << config[age].as<int>() << endl;
 
    cout << "name:" << config["name"].as<string>() << endl;
    cout << "sex:" << config["sex"].as<string>() << endl;
    cout << "age:" << config["age"].as<int>() << endl;
 
    //讀取不存在的node值,報(bào)YAML::TypedBadConversion異常
    try{
        string label = config["label"].as<string>();
    }catch(YAML::TypedBadConversion<string> &e){
        std::cout<<"label node is NULL"<<std::endl;
    }//TypedBadConversion是模板類,讀取什么類型的參數(shù)就傳入什么類型
 
 
    cout << "skills c++:" << config["skills"]["c++"].as<int>() << endl;
    cout << "skills java:" << config["skills"]["java"].as<int>() << endl;
    cout << "skills android:" << config["skills"]["android"].as<int>() << endl;
    cout << "skills python:" << config["skills"]["python"].as<int>() << endl;
     // yaml-cpp 中也可以通過(guò)迭代的方式,訪問(wèn) Node 中的內(nèi)容。
    // 比如,訪問(wèn) skills 下面的各個(gè)元素。
    for(YAML::const_iterator it= config["skills"].begin(); it != config["skills"].end();++it)
    {
        cout << it->first.as<string>() << ":" << it->second.as<int>() << endl;
    }
 
    YAML::Node test1 = YAML::Load("[1,2,3,4]");
    cout << " Type: " << test1.Type() << endl;
 
    YAML::Node test2 = YAML::Load("1");
    cout << " Type: " << test2.Type() << endl;
 
    YAML::Node test3 = YAML::Load("{'id':1,'degree':'senior'}");
    cout << " Type: " << test3.Type() << endl;
 
    ofstream fout("./testconfig.yaml"); //保存config為yaml文件
 
    config["score"] = 99;//添加新元素
 
    fout << config;
 
    fout.close();
 
 
    return 0;
}

3.4 node的增刪改查

#include <fstream>
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <assert.h>
 
int main()
{
    YAML::Node node;  
    assert(node.IsNull());  //初始化的節(jié)點(diǎn)是Null類型
    node["key"] = "value";  //當(dāng)你給它賦值鍵值對(duì),它轉(zhuǎn)變?yōu)镸ap類型
    //node.force_insert("key", "value");//這個(gè)操作和上面等價(jià),但是它不會(huì)檢查是否存在"key"鍵,不推薦使用
    if(node["mascot"])
        std::cout << node["mascot"].as<std::string>() << "\n";//單純的查詢操作不會(huì)增加一個(gè)key,當(dāng)然上面的if不會(huì)執(zhí)行
 
    node["number"] = 255;
    assert(node.IsMap());   //node是一個(gè)Map
    node["seq"].push_back("first element");
    node["seq"].push_back("second element");//node的seq下是Sequence類型,有兩個(gè)參數(shù)
 
    YAML::Node node_2;  
    node_2.push_back("first item");//如果你不給node_2鍵值對(duì),它是一個(gè)sequence類型
    node_2.push_back("second_item");
    node_2.push_back("third_item");
    std::vector<int> v = {1,3,5,7,9};//給node_2插入了一個(gè)Sequence
    node_2.push_back(v);
    assert(node_2.IsSequence());//當(dāng)然,node_2仍然是一個(gè)Sequence
 
    assert(node_2[0].as<std::string>() == "first item");
    //對(duì)于Sequence類型,你可以使用它的下標(biāo)來(lái)訪問(wèn)
    //注意這里as<T>是一個(gè)模板轉(zhuǎn)換,node_2[0]的type是NodeType::Scalar
    auto it = node_2.begin();
    for(; it != node_2.end(); it++)
        std::cout << *(it) << std::endl;
    //當(dāng)然,你也可以用迭代器來(lái)訪問(wèn)
    //他們的類型分別是NodeType::Scalar,NodeType::Scalar,NodeType::Scalar,NodeType::Sequence
    //取值時(shí)記得使用as進(jìn)行模板轉(zhuǎn)換
    node_2["key"] = "value";
    assert(node_2.IsMap());//一旦node_2接收到鍵值對(duì),它轉(zhuǎn)變?yōu)镸ap類型
    assert(node_2[0].as<std::string>() == "first item");//此時(shí),Sequence時(shí)的下標(biāo)變?yōu)樗膋ey值
    node["node_2"] = node_2;//將node_2作為node的一個(gè)子項(xiàng)
    node["pointer_to_first_element"] = node["seq"][0];//你也可以給已有的node設(shè)置一個(gè)別名,類似于一個(gè)指針
    assert(node["pointer_to_first_element"].as<std::string>() == "first element");//你可以通過(guò)這個(gè)指針訪問(wèn)那個(gè)node
 
    node.remove(node["seq"][0]);//你可以通過(guò)指定一個(gè)node來(lái)刪除它
    node.remove("pointer_to_first_element");//你也可以通過(guò)指定key來(lái)刪除它
}

如果你執(zhí)行std::cout<<node<<endl;

應(yīng)該會(huì)得到以下結(jié)果

key: value
number: 255
seq:
  - first element
  - second element
node_2:
  0: first item
  1: second_item
  2: third_item
  3:
    - 1
    - 3
    - 5
    - 7
    - 9
  key: value

以上就是C++讀寫文件(CSV,Yaml,二進(jìn)制)的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于C++讀寫文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(70.爬樓梯問(wèn)題)

    C++實(shí)現(xiàn)LeetCode(70.爬樓梯問(wèn)題)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(70.爬樓梯問(wèn)題),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)查詢本機(jī)信息的示例代碼

    C++實(shí)現(xiàn)查詢本機(jī)信息的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)查詢本機(jī)信息,并且進(jìn)行上報(bào),文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-05-05
  • 關(guān)于C++中二分法詳解

    關(guān)于C++中二分法詳解

    大家好,本篇文章主要講的是關(guān)于C++中二分法詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • C語(yǔ)言sqrt函數(shù)的實(shí)例用法講解

    C語(yǔ)言sqrt函數(shù)的實(shí)例用法講解

    在本篇文章里小編給大家整理的是關(guān)于C語(yǔ)言sqrt函數(shù)的實(shí)例內(nèi)容以及用法詳解,需要的朋友們可以參考下。
    2020-02-02
  • QML與C++交互的實(shí)現(xiàn)步驟

    QML與C++交互的實(shí)現(xiàn)步驟

    本文主要介紹了QML與C++交互的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Qt 信號(hào)自定義槽函數(shù)的實(shí)現(xiàn)

    Qt 信號(hào)自定義槽函數(shù)的實(shí)現(xiàn)

    Qt中實(shí)現(xiàn)自定義信號(hào)與槽函數(shù),信號(hào)用于發(fā)送并觸發(fā)槽函數(shù),槽函數(shù)則是具體的功能實(shí)現(xiàn),本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-11-11
  • C++ Boost Parameter超詳細(xì)講解

    C++ Boost Parameter超詳細(xì)講解

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱
    2022-11-11
  • C++實(shí)現(xiàn)簡(jiǎn)易UDP網(wǎng)絡(luò)聊天室

    C++實(shí)現(xiàn)簡(jiǎn)易UDP網(wǎng)絡(luò)聊天室

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)易UDP網(wǎng)絡(luò)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn)

    Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn)

    這篇文章主要介紹了Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 十進(jìn)制與BCD碼轉(zhuǎn)換的算法詳解

    十進(jìn)制與BCD碼轉(zhuǎn)換的算法詳解

    BCD轉(zhuǎn)換成十進(jìn)制 BCD碼是指用二進(jìn)制來(lái)表示十進(jìn)制數(shù)的編碼,即用4位二進(jìn)制來(lái)表示一位十進(jìn)制數(shù),因此4位二進(jìn)制數(shù)表示最大的十進(jìn)制數(shù)9(1001),只取十六個(gè)數(shù)中的十個(gè)數(shù)(有別于8421碼)
    2021-09-09

最新評(píng)論

仁寿县| 福建省| 宁河县| 图片| 宁波市| 开封市| 开封县| 徐州市| 金秀| 灵台县| 灵璧县| 门头沟区| 时尚| 新乐市| 永济市| 海口市| 桐城市| 河北省| 双城市| 上林县| 兴安盟| 阳朔县| 芷江| 兴业县| 苍南县| 东至县| 蕉岭县| 昌平区| 金乡县| 江都市| 苗栗县| 新乡市| 南华县| 纳雍县| 论坛| 武义县| 酉阳| 屯门区| 芒康县| 华宁县| 秀山|