一、把QQ群的聊天记录txt格式导出
消息管理器 -> 选择要导出的群 -> 右击、导出
这里要注意 : 导出之后的 文本是 unicode 编码的,需要转换 ==|| 之前不知道,搞了大半天。
重新建一个txt , 把原来的 txt 内容 复制 到 新的 txt ,保存就行了。
二、详细代码
1. head.h
1 #ifndef TxtSearch 2 #define TxtSearch 3 4 #include<string> 5 #include<map> 6 #include<set> 7 #include<iostream> 8 #include<vector> 9 #include<fstream> 10 #include<sstream> 11 #include<ctype.h> 12 13 typedef unsigned char BYTE; 14 typedef unsigned short WORD; 15 16 bool IsChineseChar(WORD DoubleByte); 17 18 void WordAndChar_print(std::string ); 19 20 21 class TextQuery 22 { 23 public: 24 25 typedef std::vector<std::string>::size_type line_no; 26 27 void read_file(std::ifstream & ); 28 std::set<line_no> run_query(const std::string&) const; 29 std::string text_line(line_no) const; 30 private: 31 void store_file( std::ifstream & ); 32 void build_map(); 33 34 35 std::vector<std::string> lines_of_text; 36 std::vector<std::string> bak_lines_of_text; 37 std::map< std::string,std::set<line_no> > word_map; 38 39 }; 40 41 void print_resluts(const std::set< TextQuery::line_no> & , 42 const std::string & , const TextQuery &); 43 44 45 #endif
2、function.cpp
1 #include"head.h" 2 3 bool IsChineseChar(WORD DoubleByte) 4 { 5 return ( (DoubleByte < 0) || (DoubleByte > 127) ); 6 } 7 8 9 void TextQuery::read_file( std::ifstream & is) 10 { 11 store_file(is); 12 build_map(); 13 } 14 15 std::set<TextQuery::line_no> TextQuery::run_query(const std::string& str) const 16 { 17 std::map<std::string, std::set<line_no> >::const_iterator 18 loc = word_map.find(str); 19 20 if(loc == word_map.end()) 21 { 22 return std::set<line_no>(); 23 } 24 25 return loc->second; 26 } 27 std::string TextQuery::text_line(line_no line_num) const 28 { 29 if(line_num < lines_of_text.size()) 30 return lines_of_text[line_num]; 31 32 throw std::out_of_range("line num is out of range"); 33 } 34 35 36 void TextQuery::store_file(std::ifstream & is) 37 { 38 std::string txtline; 39 while(std::getline(is,txtline)) 40 { 41 lines_of_text.push_back(txtline); 42 int len = txtline.length(); 43 for(int i = 0 ; i <len ; i ++) //pretreatment 44 { 45 bool b1 = 0,b2 =0; 46 if(!IsChineseChar(txtline[i]) 47 &&!isalnum(txtline[i]) ) 48 txtline[i] = ' '; 49 b1 = IsChineseChar(txtline[i]); 50 if(i + 1 < len) 51 b2 = IsChineseChar(txtline[i+1]); 52 } 53 54 bak_lines_of_text.push_back(txtline); 55 } 56 } 57 58 59 void TextQuery::build_map() 60 { 61 for(line_no line_num = 0 ; line_num != bak_lines_of_text.size() ; ++line_num) 62 { 63 std::istringstream strline(bak_lines_of_text[line_num]); 64 std::string word; 65 while(strline >> word) 66 { 67 word_map[word].insert(line_num); 68 } 69 } 70 } 71 72 void print_resluts(const std::set< TextQuery::line_no> & ss, 73 const std::string & str, const TextQuery &tq) 74 { 75 typedef std::set< TextQuery::line_no> lineset; 76 77 lineset::size_type size = ss.size(); 78 std::string path = str + ".txt"; 79 std::ofstream outfine(path); 80 outfine<<str<<" occurs "<<size <<"times"<<std::endl; 81 lineset::const_iterator it = ss.begin(); 82 83 for(; it != ss.end() ; ++ it) 84 { 85 outfine<<" ( line "<<(*it)+1<<" )"<<tq.text_line(*it)<<std::endl; 86 outfine<<" ( line "<<(*it)+2<<" )"<<tq.text_line(*it+1)<<std::endl; 87 } 88 }
3、main.cpp
1 #include"head.h" 2 3 int main() 4 { 5 std::ifstream infile("char.txt"); 6 7 if(!infile.is_open()) 8 { 9 printf("No input file! "); 10 return -1; 11 } 12 TextQuery tq; 13 tq.read_file(infile); 14 std::string query; 15 while (printf("enter user ID to look for: "), 16 std::cin>>query ) 17 { 18 std::set<TextQuery::line_no> loc = tq.run_query(query); 19 print_resluts(loc,query,tq); 20 } 21 return 0; 22 }
三、需要改进的地方
1、
1 for(; it != ss.end() ; ++ it) 2 { 3 outfine<<" ( line "<<(*it)+1<<" )"<<tq.text_line(*it)<<std::endl; 4 outfine<<" ( line "<<(*it)+2<<" )"<<tq.text_line(*it+1)<<std::endl; 5 }
找到 用户名所在的行后, 我 直接把 用户名 所在的 下一行 作为 聊天内容,但其实 聊天内容里面 可以换行。
2、
如果 聊天 内容 里面 出现 用户名,会 误以为 是 用户名 所在的行,把这行输出 并把 下一行 输出。