(原創) 如何使用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:
1
key: Elisa Bertino value: Object-Oriented Database Systems
2
key: Jeffrey D. Ullman value: Principles of Database Systems, 2nd Edition
3
key: Jeffrey D. Ullman value: A First Course in Database Systems
4
key: Jeffrey D. Ullman value: Principles of Database and Knowledge-Base Systems
5
key: R. G. G. Cattell value: Object Data Management: Object-Oriented and Extended Relational Database Systems
6
key: Stanley B. Lippman value: C++ Primer, 4th Edition
7
請按任意鍵繼續 . . .

2

3

4

5

6

7

原本的books-11-30-2006.txt文字檔內容如下
1
author = {Jeffrey D. Ullman}, title = {Principles of Database Systems, 2nd Edition}
2
3
author = {Elisa Bertino}, title = {Object-Oriented Database Systems}
4
5
author = {Jeffrey D. Ullman}, title = {A First Course in Database Systems}
6
7
author = {R. G. G. Cattell}, title = {Object Data Management: Object-Oriented and Extended Relational Database Systems}
8
9
author = {Jeffrey D. Ullman}, title = {Principles of Database and Knowledge-Base Systems}
10
11
author = {Stanley B. Lippman}, title = {C++ Primer, 4th Edition}

2

3

4

5

6

7

8

9

10

11

程式碼如下
1
/*
2
(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4
Filename : MultiMapWithStringStream.cpp
5
Compiler : Visual C++ 8.0 / ISO C++
6
Description : Demo how to use multimap and StringStream to parse text
7
Release : 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
16
using namespace std;
17
18
void print(pair<string, string>);
19
20
int 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
72
void print(pair<string, string> elem) {
73
cout << "key: " << elem.first << " value: " << elem.second << endl;
74
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

一般人處理字串,都會使用find()或find_last_of(),最後搭配substr(),32行使用StringStream來處理字串。StringStream的好用在於使用了<<和>>方式處理字串,而且可自動轉型,不需考慮型別,第32行,由於author = 這兩個字串並不是我們想處理的,可以將其>>到dump忽略之, 因為只想處理{}中間的值,所以使用find()找到'{'和'}',將中間的值湊成author StringStream。
66行為新增multimap的方式,要新增multimap,只有insert()搭配makepair一種方式而已,不像map可以使用subscripting的方式。