优秀的编程知识分享平台

网站首页 > 技术文章 正文

如何用C++程序抓出来文件中的某一列 (类似awk)?

nanyue 2024-08-05 20:16:55 技术文章 8 ℃

C++相比C的一个好处就是具有更强大的标准库,

哪怕不用面向对象那些东西,只是使用标准库,也可以方便的写出一些基本的程序。

笔者今天写了一小段稍微复杂一点的代码,

做了一个类似Linux命令awk的小应用,

就是输出一个文本文件的某一列。


这个程序用了C++标准库中的 fstream, stringstream, vector可变长度数组等等。

另外也采用了带参数的main函数,编译后的可执行程序用起来就更像一个普通的Linux命令。


我觉得读者可以直接看源代码,我把重点的地方都加了注释。

编程的主要思路:

  1. 通过ifstream把文件读进来;
  2. 先用getline抓出来文件的每一行;
  3. 然后用sstream把每一行里的每一个字符串抓出来;
  4. 把抓出来的字符串按照文件中的顺序保存在一个vector可变长度数组里;
  5. 输出需要的那一列,就是输出每一个vector的第(colunm - 1)项

关于main函数带参数,这个其实是有固定的套路的:

int main (int argc, char* argv[])

  • argc是输入参数的个数,包含程序可执行文件本身,所以argc至少是1
  • argv[] 是字符串数组,就是用户输入的每一个参数
  • 注意,可执行文件本身是第一个参数,也就是说可执行文件是 argv[0]
  • 所以程序中实际的输入参数是从argv[1]开始的
  • 由于输入的每一项都是字符串,所以如果参数需要整数int的话,需要通过atoi把字符串string转化为整数int

程序源代码:

#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;

int main (int argc, char* argv[])
{
 // input: file_name column_num
 // output: the column
 if (argc < 3) {
 cout << "Wrong input option number:" << argc -1 << endl;
 cout << "Please input: file_name column_num" << endl;
 return 0 ;
 }
 // argv[0] is the cmd itself
 ifstream input_f(argv[1]) ; // input argv 1
 if ( !input_f ) { // check if input file can be opened
 cout << "Error: the input file can not be opened" <<endl ;
 return 0 ;
 }

 int column_num = atoi(argv[2]) ; // input argv 2 
                                                      // atoi change string to int
 if ( column_num <= 0 ) { // check if input column number is correct
 //cout << column_num << endl ;
 cout << "Error: wrong column number" << endl;
 return 0;
 }

 string i_line ; // each line from file
 int line_length ; // total column number of each line
 vector<string> vec_line ; // store all element (sub string) of each line
 stringstream ss; // string stream
 string tmp_s; // each element and will be put into vec_line
 while ( getline(input_f, i_line) ) { // get each line
 ss.clear(); // init string stream
 ss << i_line ; // put each line to string stream
 vec_line.clear(); // each line need init vec_line
 while (ss >> tmp_s) { // each element (sub string) in each line
 vec_line.push_back(tmp_s); // put into vec_line
 }

 line_length = vec_line.size() ; // get total colume number of each line
 if ( column_num > 0 && column_num <= line_length) {
 cout << vec_line[column_num - 1] << endl ; // output the requried column
 } else {
 cout << "" << endl ; // if the line is empty or the required column > total column
 }
 }
 input_f.close() ;
 return 0 ;
}


测试文件 test.txt

12 24 45 9 48 5

12 24 45 9 48 5
12 24 45 9 48 5
12 24 45 9 48 5
12 24 45 9 48 5
12 24 45 9 48 5

12 24 45 9 48 5
12 24 45 9 48 5
12 24 45 9 48 5

12 24 45 9 48 5
12 24 45 9 48 5


测试结果:

g++ file_line_column.main_argv.cpp
./a.out
Wrong input option number:0
Please input: file_name column_num

./a.out test.txt
Wrong input option number:1
Please input: file_name column_num


./a.out test.tx 0
Error: the input file can not be opened


./a.out test.txt -2
Error: wrong column number


./a.out test.txt aba
Error: wrong column number


./a.out test.txt 1
12

12
12
12
12
12

12
12
12

12
12
./a.out test.txt 3
45

45
45
45
45
45

45
45
45

45
45

Tags:

最近发表
标签列表