关闭

CSV文件简介及C++实现

42人阅读 评论(0) 收藏 举报
分类:

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号):其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须象二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

CSV文件格式的通用标准并不存在,但是在RFC 4180中有基础性的描述。使用的字符编码同样没有被指定,但是7-bit ASCII是最基本的通用编码。

CSV是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。最广泛的应用是在程序之间转移表格数据,而这些程序本身是在不兼容的格式上进行操作的(往往是私有的和/或无规范的格式)。因为大量程序都支持某种CSV变体,至少是作为一种可选择的输入/输出格式。

“CSV”并不是一种单一的、定义明确的格式(尽管RFC 4180有一个被通常使用的定义)。因此在实践中,术语”CSV”泛指具有以下特征的任何文件:

(1)、纯文本,使用某个字符集,比如ASCII、Unicode、EBCDIC或GB2312(简体中文)等;

(2)、由记录组成(典型的是每行一条记录);

(3)、每条记录被分隔符分隔为字段(典型分隔符有逗号、分号或制表符;有时分隔符可以包括可选的空格);

(4)、每条记录都有同样的字段序列。

在这些常规的约束条件下,存在着许多CSV变体,故CSV文件并不完全互通。然而,这些变异非常小,并且有许多应用程序允许用户预览文件(这是可行的,因为它是纯文本),然后指定分隔符、转义规则等。如果一个特定CSV文件的变异过大,超出了特定接收程序的支持范围,那么可行的做法往往是人工检查并编辑文件,或通过简单的程序来修复问题。因此在实践中,CSV文件还是非常方便的。

CSV格式最好被用来表现记录集合或序列,其中的每条记录都有完全相同的字段序列。CSV格式没有被限定于某个特定字符集。不管用Unicode还是用ASCII,都没有问题(尽管特定程序支持的CSV可能会有它们自己的局限性)。甚至从一个字符集翻译到另一个字符集,CSV文件都不会有问题(不象几乎所有的私有数据格式)。然而,CSV不提供任何途径来表明使用的是什么字符集。

“CSV”格式中大量变体的存在说明并没有一个”CSV标准”。在常见用法中,几乎任何定界符分隔的文本数据都可以被统称为”CSV”文件。不同的CSV格式可能不会兼容。

以上内容介绍主要来自: 维基百科 

以下code 是参考 https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c ,可以实现对简单csv文件的解析:

如果csv文件比较复杂,可以试试github上的一个开源库:  https://github.com/ben-strasser/fast-cpp-csv-parser

parse_csv.hpp:

#ifndef FBC_CPPBASE_TEST_PARSE_CSV_HPP_
#define FBC_CPPBASE_TEST_PARSE_CSV_HPP_

// reference: https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c?page=1&tab=votes#tab-top

#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

class CSVRow {
public:
	std::string const& operator[](std::size_t index) const { return m_data[index]; }
	std::size_t size() const { return m_data.size(); }

	void readNextRow(std::istream& str)
	{
		std::string line;
		std::getline(str, line);

		std::stringstream lineStream(line);
		std::string cell;

		m_data.clear();
		while (std::getline(lineStream, cell, ',')) {
			m_data.push_back(cell);
		}
		// This checks for a trailing comma with no data after it.
		if (!lineStream && cell.empty()) {
			// If there was a trailing comma then add an empty element.
			m_data.push_back("");
		}
	}

private:
	std::vector<std::string>  m_data;
};

std::istream& operator>>(std::istream& str, CSVRow& data)
{
	data.readNextRow(str);
	return str;
}

class CSVIterator {
public:
	/*typedef std::input_iterator_tag iterator_category;
	typedef CSVRow value_type;
	typedef std::size_t difference_type;
	typedef CSVRow* pointer;
	typedef CSVRow& reference;*/

	CSVIterator(std::istream& str) :m_str(str.good() ? &str : nullptr) { ++(*this); }
	CSVIterator() :m_str(nullptr) {}

	// Pre Increment
	CSVIterator& operator++() { if (m_str) { if (!((*m_str) >> m_row)){ m_str = nullptr; } }return *this; }
	// Post increment
	CSVIterator operator++(int) { CSVIterator tmp(*this); ++(*this); return tmp; }
	CSVRow const& operator*() const { return m_row; }
	CSVRow const* operator->() const { return &m_row; }

	bool operator==(CSVIterator const& rhs) { return ((this == &rhs) || ((this->m_str == nullptr) && (rhs.m_str == nullptr))); }
	bool operator!=(CSVIterator const& rhs) { return !((*this) == rhs); }

private:
	std::istream* m_str;
	CSVRow m_row;
};

#endif // FBC_CPPBASE_TEST_PARSE_CSV_HPP_
test_parse_csv.cpp:

#include "test_parse_cvs.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include "parse_csv.hpp"

namespace parse_cvs_ {

int test_parse_cvs_1()
{
	std::ifstream file("E:/GitCode/Messy_Test/testdata/test_csv.csv");

	std::vector<std::vector<std::string>> data;
	CSVIterator loop(file);
	for (; loop != CSVIterator(); ++loop) {
		CSVRow row = *loop;
		std::vector<std::string> tmp(row.size());
		for (int i = 0; i < row.size(); ++i) {
			tmp[i] = row[i];
		}
		data.emplace_back(tmp);
	}

	for (int i = 0; i < data.size(); ++i) {
		for (int j = 0; j < data[i].size(); ++j) {
			fprintf(stdout, "%s\t", data[i][j].c_str());
		}
		fprintf(stdout, "\n");
	}

	return 0;
}

} // namespace parse_cvs_
test_csv.csv测试数据如下:


执行结果如下:


GitHub: https://github.com/fengbingchun/Messy_Test 

0
0
查看评论

C++遍历文件夹中的文件并把结果保存到csv中

StaDir.h文件 #pragma once #include "browsedir.h" class CStaDir : public CBrowseDir { public: CStaDir(void); ~CStaDir(void); int m_nFileCou...
  • guanyuqiu
  • guanyuqiu
  • 2017-07-06 14:21
  • 652

C++读写表格csv——文本与表格完美桥接者

很多人在开发过程中可能都会遇到相对于表格进行读写操作,C++读写表格也有很多种方法,比如说通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现。 但是终究需要引用一些文件以及过程繁琐。 我们知道C语言的FILE类对于读写二进制文件非常的方便 比如: string th...
  • sm9sun
  • sm9sun
  • 2016-11-24 13:15
  • 851

C++读取CSV文件中的数据

CSV文件是一种文本文件,表示的是Excel表格数据,可以由办公软件Excel轻松生成。为了在程序中使用Excel数据,就需要以文本的形式操作Excel数据,具体就是操作CSV表格数据。如下所示, #include #include #include #include #include ...
  • u013232740
  • u013232740
  • 2016-03-08 16:24
  • 9459

c++中将数据存储到.csv文件中(类似于xsl表格)

ofstream ofile; ofile.open("result.csv",ios::out | ios::trunc);       //判断.csv文件是否存在,不存在则建立 ofile int a[10][5]; for(int...
  • u014581740
  • u014581740
  • 2017-04-14 09:31
  • 766

C/C++读写csv文件

csv文件其实就是文本文件,每行字段用逗号分隔。 代码 #include #include #include #include #include using namespace std; int main() { // 写文件 ofstream outFile; o...
  • u012234115
  • u012234115
  • 2017-03-21 18:39
  • 6172

c++读取csv文件

目前任务需要处理大量excel表格,为便于处理转化为csv格式。csv是一种以半角逗号和换行符作为分割的excl表格格式,用记事本直接打开便很清楚的看到内部构造。之前曾经用C#处理,比较方便,直接将csv读取为DataTable格式进行处理,网上有现成代码。窃以为应该多练练c++,就试一下。菜鸟一个...
  • JarvisKao
  • JarvisKao
  • 2015-10-29 15:52
  • 3095

c++读取csv文件和写入文件

一直以来感觉对文件的读写和流的使用比较陌生,最近在写的一个project正好需要读取csv文件的数据和创建新的csv文件,于是在网上看了一些对csv文件读写操作的文章,基本了解了大概的操作。 读取.csv文件 注意:.csv文件是用','作为分隔符,所以每次读取到...
  • lovingAlice
  • lovingAlice
  • 2016-04-05 22:49
  • 11802

CSV读取类,C++ STL实现

CSV文件作为一种简单易用的信息存储文件,有着非常广泛的用途,在游戏开发行业的应用尤为普遍,它比普通ini文件记录信息更加方便,具有更加严谨的格式信息,同时又没有数据库存储数据那么复杂。 它的记录形式通常以逗号为字段间分隔符,以回车为每条记录间分割符的简单文本格式,通过Excel打开如下所示: ...
  • zhliu1991
  • zhliu1991
  • 2015-01-22 15:08
  • 953

C++ .csv文件处理 与 sstream应用

在window上用C++处理.csv文件 1. 一般文件的读取利用<fstream>头文件 2.处理.csv文件 3.了解<sstream>
  • qq_29596177
  • qq_29596177
  • 2016-03-16 22:42
  • 887

C++实现人脸识别csv文件的写入(加labels)

前面也写了一个csv是没有加label的(http://blog.csdn.net/u013812682/article/details/52013074), 上次写完因为有点事所以没看这块,才发现少加了label,所以在这里补上 orl下载地址:http://www.cl.cam.ac.uk/...
  • u013812682
  • u013812682
  • 2016-08-17 09:31
  • 669
    个人资料
    • 访问:3637921次
    • 积分:35906
    • 等级:
    • 排名:第138名
    • 原创:524篇
    • 转载:140篇
    • 译文:0篇
    • 评论:1908条
    最新评论