StringTokenizer
StringTokenizer là một class thường được viết trong các dự án. Đó là một class dùng để xử lý chuỗi, chia tách chuỗi thành các chuỗi con (token) được phân cách bởi các ký tự định nghĩa trước (delimiter). Ví dụ:
“Hoang Tran:1982:Hanoi University of Technology” được phân cách bởi ký tự “:” để thu được thông tin tương ứng về tên, năm sinh và trường học.
Có rất nhiều cách thể hiện lớp StringTokenizer này ở các ngôn ngữ khác nhau (Java thì đã có trong JDK của nó rồi) Bạn có thể google để tìm tham khảo các cách viết đó. Dựa trên ý tưởng của java, chúng ta sẽ xây dựng một lớp StringTokenizer hữu dụng trong C++.
Trong nhiều cách viết lớp này ở trên mạng thì mình cũng nhận ra rằng cách viết ở dự án cũ là tối ưu, hay và dễ hiểu nhất
Sử dụng deque làm storage data cho lớp StringTokenizer sẽ làm cho quá trình insert cũng như delete các beginning và end của container rất nhanh.
Đây là lớp StringTokenizer đã được thêm bớt chút ít sau khi đi chôm
class StringTokenizer { public: typedef std::deque<std::string>::iterator iterator; StringTokenizer( std::string str, std::string delim = " \t\r\f\n", bool split = false ) { std::string::size_type pos; while (( pos = str.find_first_of( delim ) ) != std::string::npos ) { if ( split && pos == 0 ) { _tokens.push_back( std::string() ); } else if ( pos > 0 ) { _tokens.push_back( str.substr( 0, pos ) ); } ++pos; /* Skip consecutive delimiter characters when tokenising. */ if (( ! split ) && ( ! str.empty() )) { for( ; delim.find( str[pos] ) != std::string::npos; ++pos ) { /* Empty loop. */ } } str = str.substr( pos ); } if (( split ) || ( ! str.empty() )) { _tokens.push_back( str ); } } StringTokenizer( const StringTokenizer &rhs ) { *this = rhs; } virtual ~StringTokenizer() { } iterator begin() { return _tokens.begin(); } iterator end() { return _tokens.end(); } StringTokenizer& operator=( const StringTokenizer &rhs ) { if ( &rhs != this ) { _tokens = rhs._tokens; } return *this; } const std::string& operator [] ( int index ) { return _tokens[ index ]; } int size() const { return _tokens.size(); } bool empty() const { return size() == 0; } bool has_more_tokens() { return (_tokens.size() > 0); } std::string next_token() { std::string tok = _tokens.front(); _tokens.pop_front(); return tok; } private: std::deque<std::string> _tokens; };
Hay phết nhỉ. Chỉ bằng mấy vòng lặp và các hàm xử lí xâu mà tạo được 1 lớp rất có ích. Tuy nhiên không hiểu sao em thường ít dùng cái StringTokenizer trong PMS mà thường dùng các hàm find của std::string luôn cho nhanh
(trong các trường hợp chỉ cần lấy ra 1 trường thay vì tất cả các trường).
Đọc bài viết này tự nhiên nhớ đến awk. Cái xâu “Hoang Tran:1982:Hanoi University of Technology”mà nhét vào awk thì roẹt một phát là trường nào ra trường ý.
Tất nhiên trong trường hợp lấy một field thì cần gì cái này. Nếu là script thì chạy awk chứ trong cpp thì chẳng nhẽ là dùng system() hay exec() để excute cái awk đó. Lúc đó sẽ tạo thêm một process mới và chẳng nhanh tí nào.
Cái StringTokenizer này thường đi kèm để viết một cái ConfigurationLoader hoặc Properties để parse những file configure (/etc/*.conf)
các bạn có biết tài liệu nào hay phần mền nào tra cứu các lớp hay phương thức trong java ko? mình mới học nên ko biết. Ko biết nó có cái nào giống như MSDN của c++ ko?
java có ko?
Lên mạng search Java APIs documentation là có.