关键词:C++, csv, string find, string replace, istringstream, vector, sort, for_each
csv文件的特点:
csv文件一般是从Excel表格保存过来的,
每一列的内容用逗号隔开,中间没有空格。
案例中的csv文件存储的是每一个员工的姓名,工号和职级。
文件内容如下:
zhangsan,100,1
Lisi,101,2
wangwu,103,4
xiaoliu,102,3
dashan,105,5
ahuan,106,1
laoniu,104,3
kaixin,109,2
liuliu,107,4
hongbo,108,5
lili,110,3
小案例的目标:
笔者今天要讲的案例是把上面这个csv文件用C++读进结构体struct变量,
然后再按照职级,从小到大排序,然后输出。
编程的思路:
- 用getline得到每一行的内容,赋值给一个string对象;
- 用string的成员函数find()找到逗号的位置;
- 用string的成员函数replace()将逗号替换成空格;
- 用很神奇的istringstream作为媒介,将每一行的内容赋值给结构体Employee的成员变量;
- 将得到所有的结构体Employee对象放到vector容器中;
- 用sort对vector进行排序,用for_each输出。
代码中几个细节:
string的find()成员函数的用法:
find_result = i_line.find("," , find_start) ;
- 从string对象i_line中,下标find_start开始查找字符串“,” ;
- 如果找到,就返回被查找字符串在i_line中的开始位置的下标;
- 如果找不到,就返回string::npos。
string的replace()函数的用法:
i_line = i_line.replace(find_result, 1, " ");
- 将string对象i_line,下标为find_result开始的,长度为1的字符串,替换为空格“ ” 。
很神奇的istringstream的用法:
istringstream inputString(i_line);
inputString >> i_employee.Name >> i_employee.id >> i_employee.grade ;
- istringstream 定义一个input stream的对象 inputString;
- 用string类型的对象i_line来初始化inputString;
- 然后就可以把inputString像cin一样使用;
- 神奇的地方是,可以和cin一样,根据左侧变量的类型进行赋值;
- 也就是自动进行字符串到任何类型变量的转换。
代码最后的sort自定义规则排序和for_each输出结构体成员变量的值,
都在笔者之前的文章中已经介绍过了,就不细说了。
程序源代码:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct Employee {
string Name;
int id;
int grade;
} ;
// sort rule by grade
struct Empolyee_sort_rule { // sort by grade
bool operator() (const Employee & e1, const Employee & e2) const {
if( e1.grade < e2.grade ) // the smaller grade in front
return true;
return false;
}
};
void printEmployee(Employee e) {
cout << e.Name << "t" << e.id << "t" << e.grade << endl ;
}
int main ()
{
// open file
ifstream input_f("./test_employee.csv") ; // input argv 1
if ( !input_f ) { // check if input file can be opened
cout << "Error: the input file can not be opened" < all_lines ; // container to store all lines
istringstream inputString; // put every line string to input stream;
int find_result = 0;
int find_start = 0;
while ( getline(input_f, i_line) ) { // get each line
find_result = 0;
find_start = 0 ;
find_result = i_line.find("," , find_start) ; // find , loc
while (find_result != string::npos) {
i_line = i_line.replace(find_result, 1, " "); // replace , with " "
find_start = find_result + 1 ; // next find
find_result = i_line.find("," , find_start) ;
}
istringstream inputString(i_line); // put string to input stream
inputString >> i_employee.Name >> i_employee.id >> i_employee.grade ; // stream to variable
all_lines.push_back(i_employee);
}
//sort by grade
sort(all_lines.begin(), all_lines.end(), Empolyee_sort_rule());
// output
for_each(all_lines.begin(), all_lines.end(), printEmployee) ;
input_f.close() ;
return 0 ;
}
测试结果:
g++ file_sort.vector.csv.cpp -o sort_csv
./sort_csv
zhangsan 100 1
ahuan 106 1
Lisi 101 2
kaixin 109 2
xiaoliu 102 3
laoniu 104 3
lili 110 3
wangwu 103 4
liuliu 107 4
dashan 105 5
hongbo 108 5