1、getline() 将读取的每一行保存至 vector<string> v_lines
2、每循环一次 将一行(*iter_line)划分成一个个单词,保存至 vector<string> v_words,并统计至 map<string,int> m_words;
代码:
1 /*
2 * FILE: WordFrequency.cpp
3 * -----------------------
4 * DATE: 20170819
5 * This program computes the frequency of words in a text file.
6 *
7 */
8
9 #include <iostream>
10 #include <iomanip> // setw(n) 将输出字段的宽度设置为n个字符
11 #include <fstream>
12 #include <vector>
13 #include <map>
14 #include <algorithm> // transform() 将字符串string转为小写
15
16 void OpenFile(std::ifstream &infile)
17 {
18 std::string prompt = "Please input filename: ";
19 while(true)
20 {
21 std::cout<< prompt;
22 std::string filename;
23 getline(std::cin, filename); // 将输入的文件名保存至变量filename
24 // 打开文件 infile.open("test.txt");
25 // 如果文件名存储在string变量中,则 infile.open(filename.c_str());
26 infile.open(filename.c_str());
27 if(!infile.fail())
28 return;
29 infile.clear(); //重新输入前调用clear重置
30 std::cout<< "Unable to open the file. Try again." <<std::endl;
31 }
32 }
33
34 /*
35 * Extracts words from the line into the string vector words
36 * 将一行字符串 提取为一个个单词 存储至 顺序容器vector
37 * extract: 提取
38 */
39 void extractWords(std::string line, std::vector<std::string> &v_words)
40 {
41 v_words.clear();
42 int start = -1;
43 for(int i = 0; i < line.length(); i++)
44 {
45 if(isalpha(line[i])) // isalpha() 如果是字母,则返回true
46 {
47 if(start == -1)
48 start = i;
49 }
50 else
51 {
52 if(start >= 0)
53 {
54 //push_back() 向顺序容器vector中 添加元素
55 //substr(pos, n) 从pos位置开始截取n个字符,或直到末尾
56 v_words.push_back(line.substr(start, i - start));
57 start = -1;
58 }
59 }
60 }
61 if(start >= 0)
62 v_words.push_back(line.substr(start));
63 }
64
65 /*
66 * Counts words in the input stream, storing the results in map<string,int>
67 * 关联容器 map
68 */
69 void countWords(std::istream &is, std::map<std::string,int> &m_words)
70 {
71 std::vector<std::string> v_lines;
72 std::vector<std::string> v_words;
73 std::string str;
74
75 while(getline(is, str)) // getline() 一行一行读取
76 v_lines.push_back(str); // 将每行字符串保存至 顺序容器vector
77 for(std::vector<std::string>::iterator iter_line = v_lines.begin(); iter_line != v_lines.end(); iter_line++)
78 {
79 extractWords(*iter_line, v_words); // 每循环一次,提取一行中的单词
80 for(std::vector<std::string>::iterator iter_word = v_words.begin(); iter_word != v_words.end(); iter_word++)
81 {
82 // 将提取的单词 统计并保存至关联容器map
83 // 库<algorithm> 中的 transform() 将字符串转为小写
84 transform((*iter_word).begin(), (*iter_word).end(), (*iter_word).begin(), ::tolower);
85 m_words[*iter_word]++; //保存至 关联容器map
86 }
87 }
88 }
89
90 /* Display the map */
91 void displayMap(std::map<std::string,int> &m)
92 {
93 for(std::map<std::string,int>::iterator iter = m.begin(); iter != m.end(); iter++)
94 // 库<iomanip> 中的setw() 设置输出字段的宽度
95 std::cout<< std::left << std::setw(15) << iter->first
96 << std::right << std::setw(15) << iter->second <<std::endl;
97 }
98
99 int main()
100 {
101 std::ifstream infile;
102 std::map<std::string,int> m_words;
103 OpenFile(infile);
104 countWords(infile, m_words);
105
106 infile.close();
107 displayMap(m_words);
108 return 0;
109 }