(原創) 如何使用multimap? 如何使用StringStream解析文字檔? (C/C++) (STL)
map迷人之處在於一次存key和value兩個值,且key是唯一的,但若遇到key可重複的情況呢?STL另外提供了multimap...
這是我修C++ Lab的題目,讓我們練習使用multimap,但其中能有許多小技巧值得學習:
Write a program to read, parse and insert the entries containing author-title records (file books-11-30-2006.txt). Insert the author-title pairs into a std:multimap. Your ouputs should look like:
1key: Elisa Bertino value: Object-Oriented Database Systems
2key: Jeffrey D. Ullman value: Principles of Database Systems, 2nd Edition
3key: Jeffrey D. Ullman value: A First Course in Database Systems
4key: Jeffrey D. Ullman value: Principles of Database and Knowledge-Base Systems
5key: R. G. G. Cattell value: Object Data Management: Object-Oriented and Extended Relational Database Systems
6key: Stanley B. Lippman value: C++ Primer, 4th Edition
7請按任意鍵繼續 . . .
2key: Jeffrey D. Ullman value: Principles of Database Systems, 2nd Edition
3key: Jeffrey D. Ullman value: A First Course in Database Systems
4key: Jeffrey D. Ullman value: Principles of Database and Knowledge-Base Systems
5key: R. G. G. Cattell value: Object Data Management: Object-Oriented and Extended Relational Database Systems
6key: Stanley B. Lippman value: C++ Primer, 4th Edition
7請按任意鍵繼續 . . .
原本的books-11-30-2006.txt文字檔內容如下
1author = {Jeffrey D. Ullman}, title = {Principles of Database Systems, 2nd Edition}
2
3author = {Elisa Bertino}, title = {Object-Oriented Database Systems}
4
5author = {Jeffrey D. Ullman}, title = {A First Course in Database Systems}
6
7author = {R. G. G. Cattell}, title = {Object Data Management: Object-Oriented and Extended Relational Database Systems}
8
9author = {Jeffrey D. Ullman}, title = {Principles of Database and Knowledge-Base Systems}
10
11author = {Stanley B. Lippman}, title = {C++ Primer, 4th Edition}
2
3author = {Elisa Bertino}, title = {Object-Oriented Database Systems}
4
5author = {Jeffrey D. Ullman}, title = {A First Course in Database Systems}
6
7author = {R. G. G. Cattell}, title = {Object Data Management: Object-Oriented and Extended Relational Database Systems}
8
9author = {Jeffrey D. Ullman}, title = {Principles of Database and Knowledge-Base Systems}
10
11author = {Stanley B. Lippman}, title = {C++ Primer, 4th Edition}
程式碼如下
1/*
2(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4Filename : MultiMapWithStringStream.cpp
5Compiler : Visual C++ 8.0 / ISO C++
6Description : Demo how to use multimap and StringStream to parse text
7Release : 12/14/2006 1.0
8*/
9#include <iostream>
10#include <fstream>
11#include <sstream>
12#include <map>
13#include <string>
14#include <algorithm>
15
16using namespace std;
17
18void print(pair<string, string>);
19
20int main() {
21 typedef multimap<string, string> AuthorBooks;
22 AuthorBooks authorBooks;
23
24 ifstream input("books-11-30-2006.txt");
25 string line, word, dump;
26 while(getline(input,line)) {
27 if (line == "") {
28 continue;
29 }
30
31 istringstream ss(line);
32 ss >> dump >> dump; // Ignore author =
33
34 ostringstream author;
35 while(ss >> word) {
36 if (word.find('{') != string::npos) {
37 // Begin with 1 for not include '{'
38 author << word.substr(1);
39 }
40 else if (word.find('}') != string::npos) {
41 // End with word.size()-2 for not include "},"
42 author << " " << word.substr(0,word.size()-2);
43 break;
44 }
45 else {
46 author << " " << word;
47 }
48 }
49
50 ostringstream book;
51 ss >> dump >> dump; // Ignore title =
52 while(ss >> word) {
53 if (word.find('{') != string::npos) {
54 book << word.substr(1);
55 }
56 else if (word.find('}') != string::npos) {
57 book << " " << word.substr(0,word.size()-1);
58 break;
59 }
60 else {
61 book << " " << word;
62 }
63 }
64
65 // StringString to string : author.str()
66 authorBooks.insert(make_pair(author.str(),book.str()));
67 }
68
69 for_each(authorBooks.begin(), authorBooks.end(), print);
70}
71
72void print(pair<string, string> elem) {
73 cout << "key: " << elem.first << " value: " << elem.second << endl;
74}
2(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4Filename : MultiMapWithStringStream.cpp
5Compiler : Visual C++ 8.0 / ISO C++
6Description : Demo how to use multimap and StringStream to parse text
7Release : 12/14/2006 1.0
8*/
9#include <iostream>
10#include <fstream>
11#include <sstream>
12#include <map>
13#include <string>
14#include <algorithm>
15
16using namespace std;
17
18void print(pair<string, string>);
19
20int main() {
21 typedef multimap<string, string> AuthorBooks;
22 AuthorBooks authorBooks;
23
24 ifstream input("books-11-30-2006.txt");
25 string line, word, dump;
26 while(getline(input,line)) {
27 if (line == "") {
28 continue;
29 }
30
31 istringstream ss(line);
32 ss >> dump >> dump; // Ignore author =
33
34 ostringstream author;
35 while(ss >> word) {
36 if (word.find('{') != string::npos) {
37 // Begin with 1 for not include '{'
38 author << word.substr(1);
39 }
40 else if (word.find('}') != string::npos) {
41 // End with word.size()-2 for not include "},"
42 author << " " << word.substr(0,word.size()-2);
43 break;
44 }
45 else {
46 author << " " << word;
47 }
48 }
49
50 ostringstream book;
51 ss >> dump >> dump; // Ignore title =
52 while(ss >> word) {
53 if (word.find('{') != string::npos) {
54 book << word.substr(1);
55 }
56 else if (word.find('}') != string::npos) {
57 book << " " << word.substr(0,word.size()-1);
58 break;
59 }
60 else {
61 book << " " << word;
62 }
63 }
64
65 // StringString to string : author.str()
66 authorBooks.insert(make_pair(author.str(),book.str()));
67 }
68
69 for_each(authorBooks.begin(), authorBooks.end(), print);
70}
71
72void print(pair<string, string> elem) {
73 cout << "key: " << elem.first << " value: " << elem.second << endl;
74}
一般人處理字串,都會使用find()或find_last_of(),最後搭配substr(),32行使用StringStream來處理字串。StringStream的好用在於使用了<<和>>方式處理字串,而且可自動轉型,不需考慮型別,第32行,由於author = 這兩個字串並不是我們想處理的,可以將其>>到dump忽略之, 因為只想處理{}中間的值,所以使用find()找到'{'和'}',將中間的值湊成author StringStream。
66行為新增multimap的方式,要新增multimap,只有insert()搭配makepair一種方式而已,不像map可以使用subscripting的方式。