C++相比C的一个好处就是具有更强大的标准库,
哪怕不用面向对象那些东西,只是使用标准库,也可以方便的写出一些基本的程序。
笔者今天写了一小段稍微复杂一点的代码,
做了一个类似Linux命令awk的小应用,
就是输出一个文本文件的某一列。
这个程序用了C++标准库中的 fstream, stringstream, vector可变长度数组等等。
另外也采用了带参数的main函数,编译后的可执行程序用起来就更像一个普通的Linux命令。
我觉得读者可以直接看源代码,我把重点的地方都加了注释。
编程的主要思路:
- 通过ifstream把文件读进来;
- 先用getline抓出来文件的每一行;
- 然后用sstream把每一行里的每一个字符串抓出来;
- 把抓出来的字符串按照文件中的顺序保存在一个vector可变长度数组里;
- 输出需要的那一列,就是输出每一个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