前言
平常使用python处理csv
有numpy
库和pandas
库非常方便,现在有任务需要使用c++处理csv
文件,这里记录一下处理csv
的代码。这里将每个小格中的数据按照字符串推入到vector
中。
下面我们以这个表格做示例代码.
name | income | expenditure | address |
---|---|---|---|
zhangsan | 3000 | 1200 | 中国 北京市 |
lisi | 2032.5 | 789.2 | 中国 陕西省 |
这里尽量包含字符串、整型、浮点数、汉字多个类型
一、基础准备
1、数据类型转换函数
字符串和其他数据类型转换 (<stdlib.h>中的函数)
函数 | 原类型 | 转换类型 | example |
---|---|---|---|
atof | string | double | atof("0.3") => 0.3 |
atoi | string | integer | atoi("123") => 123 |
atol | string | long integer | atol("123") => 123 |
atoll | string | long long integer | atoll("123") => 123 |
std::to_string | int|float|double|... | string | to_string(0.3) => “0.3” |
2、行数据读取与分割
这里使用
std::getline()
,可以类似python
的字符串分割split
有兴趣的可以自行封装一个返回vector类型的函数
先介绍一下函数std::getline()
// C++内部文件描述
template<typename _CharT, typename _Traits, typename _Alloc>
basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
//Read a line from stream into a string.
//Parameters:
//__is – Input stream. //输入流
//__str – Buffer to store into. //每个word存储地址
//__delim – Character marking end of line. //分隔符
//Returns:
//Reference to the input stream. Stores characters from __is into __str until __delim is
//found, the end of the stream is encountered, or str.max_size() is reached. Any previous
//contents of __str are erased. If __delim is encountered, it is extracted but not stored
//into __str.
二、csv文件写入
代码如下(示例):
#include <iostream>
#include <fstream>
int main()
{
std::ofstream outFile;
outFile.open("test.csv", std::ios::out | std::ios::trunc);
// 写入标题行
outFile << "name" << ','
<< "income" << ','
<< "expenditure" << ','
<< "addr" << std::endl;
// ********写入两行数据*********
// 写入字符串(数字)
outFile << "zhangsan" << ','
<< "3000" << ','
<< "1200" << ','
<< "中国 北京市" << std::endl;
// 写入浮点数(转为字符串)
outFile << "lisi" << ','
<< std::to_string(2032.1) << ','
<< std::to_string(789.2) << ','
<< "中国 陕西省" << std::endl;
outFile.close();
return 0;
}
二、csv文件读取
代码如下:
#include <iostream>
#include <istream>
#include <streambuf>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <stdlib.h>
int main()
{
std::ifstream csv_data("test.csv", std::ios::in);
std::string line;
if (!csv_data.is_open())
{
std::cout << "Error: opening file fail" << std::endl;
std::exit(1);
}
std::istringstream sin; //将整行字符串line读入到字符串istringstream中
std::vector<std::string> words; //声明一个字符串向量
std::string word;
// 读取标题行
std::getline(csv_data, line);
// 读取数据
while (std::getline(csv_data, line))
{
sin.clear();
sin.str(line);
words.clear();
while (std::getline(sin, word, ',')) //将字符串流sin中的字符读到field字符串中,以逗号为分隔符
{
words.push_back(word); //将每一格中的数据逐个push
std::cout << word;
// std::cout << atol(word.c_str());
}
std::cout << std::endl;
// do something。。。
}
csv_data.close();
return 0;
}
三、demo–读写
#include <iostream>
#include <fstream>
#include <istream>
#include <sstream>
#include <streambuf>
#include <vector>
#include <string>
#include <stdlib.h>
void printCsv(std::vector<std::string> line_data)
{
std::cout << line_data[0]
// << atof(line_data[1].c_str())
// << atof(line_data[2].c_str())
<< line_data[1]
<< line_data[2]
<< line_data[3]
<< std::endl;
}
int main()
{
std::ifstream csv_data("test.csv", std::ios::in);
std::string line;
if (!csv_data.is_open())
{
std::cout << "Error: opening file fail" << std::endl;
std::exit(1);
}
std::vector<std::string> words; //声明一个字符串向量
std::string word;
// ------------读取数据-----------------
// 读取标题行
std::getline(csv_data, line);
std::istringstream sin;
// 按行读取数据
while (std::getline(csv_data, line))
{
// 清空vector,只存当前行的数据
words.clear();
sin.clear();
sin.str(line);
while (std::getline(sin, word, ',')) //将字符串流sin中的字符读到field字符串中,以逗号为分隔符
{
std::cout << word << std::endl;
words.push_back(word); //将每一格中的数据逐个push
}
printCsv(words);
}
csv_data.close();
std::ofstream outFile;
outFile.open("test.csv", std::ios::out | std::ios::trunc);
// 写入标题行
outFile << "name" << ','
<< "income" << ','
<< "expenditure" << ','
<< "addr" << std::endl;
// ********写入两行数据*********
// 写入字符串(数字)
outFile << "zhangsan" << ','
<< "3000" << ','
<< "1200" << ','
<< "中国 陕西省" << std::endl;
// 写入浮点数(转为字符串)
outFile << "lisi" << ','
<< std::to_string(2032.1) << ','
<< std::to_string(789.2) << ','
<< "中国 北京市" << std::endl;
outFile.close();
return 0;
}