关键词: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