登陆"QQ同步助手"的网页,我们可以将里面的短信信息批量导出到本地存为*.csv文件。该文件可以用Excel打开,看到里面的短信信息。
在用Qt编写一个小程序的时候我想提取这里面的短信信息。作为一个小程序来说,不管是用连接数据库的方式打开该文件,还是使用与平台相关的ActiveX,或者是使用网上那些开源的类库都显得很复杂。我找过一些与平台无关的类库,看着里面那些大量的函数和说明,头就晕了。
鉴于CSV文件其实就是一种格式化的文本文件,我就写了一个类,专门读取从"QQ同步助手"中导出的CSV格式的短信信息。虽然通用性不强,不过小巧好用,符合自己的习惯:)
这里贴出来,业余水准仅供参考:
msg.h
#ifndef MSGS_H
#define MSGS_H
#include <QString>
#include <QList>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <QStringList>
#include <fstream>
class msg{
public:
msg(){message="";name="";phoneNo="";time="";}
QString message;
QString name;
QString phoneNo;
QString time;
};
class msgs{
public:
msgs(){}
bool csvToNewForm(std::string filename,std::string ofilename); //读取*.csv文件,做第一步转换。将短信与短信用特殊符号分割开来,该函数用标准C++编写
bool getFmtMsg(QString filename,QString ofilename); //将上一步转换出的文件读入,转换为QStringList并保存
bool loadBinMsgs(QString filename);//载入上一步的二进制文件,存入QList<msg> allMsgs中,方便其他程序使用
bool saveMsgsToBin(QString filename);//将QList<msg> allMsgs中的短信保存为QStringList,并保存
QList<msg> allMsgs;
private:
void help_loadQSL(QStringList &list);
};
#endif // MSGS_H
msg.cpp
#include"msgs.h"
bool msgs::getFmtMsg(QString filename,QString ofilename){
QFile file(filename);
if(!file.open(QIODevice::ReadOnly)){
//std::cout << "无法打开格式化信息文件" << filename.toStdString() << std::endl;
return false;
}
QTextStream in(&file);
QString m=in.readAll();
file.close();
QStringList list = m.split("№");
//去除末尾无用空数据
list.removeLast();
for(int i=0;i<list.length();i++){
QString temp=list.at(i);
while(!temp.isEmpty()&&(temp[0]==QChar('\n')||temp[0]==QChar('\r')))
temp.remove(0,1);
while(!temp.isEmpty()&&(temp[temp.length()-1]==QChar('\n')||temp[temp.length()-1]==QChar('\r')))
temp.remove(temp.length()-1,1);
list.replace(i,temp);
}
QFile outfile(ofilename);
if(!outfile.open(QIODevice::WriteOnly)){
//std::cout << "无法创建程序数据文件" << ofilename.toStdString() << std::endl;
return false;
}
QDataStream out(&outfile);
out << list;
outfile.close();
return true;
}
void msgs::help_loadQSL(QStringList &list){
if(!allMsgs.isEmpty())
allMsgs.clear();
msg data;
for(int i=0;i+3<list.length();i+=4){
data.message=list.at(i);
data.name=list.at(i+1);
data.phoneNo=list.at(i+2);
data.time=list.at(i+3);
allMsgs.push_back(data);
}
}
bool msgs::loadBinMsgs(QString filename){
QFile file(filename);
if(!file.open(QIODevice::ReadOnly)){
//std::cout << "无法载入程序数据文件" << filename.toStdString() << std::endl;
return false;
}
QDataStream in(&file);
QStringList list;
in >> list;
help_loadQSL(list);
file.close();
return true;
}
bool msgs::csvToNewForm(std::string filename, std::string ofilename){
std::fstream file(filename.data(),std::ios::in);
if(!file){
//std::cout << "无法打开信息源文件" << filename << std::endl;
return false;
}
char t;
file.seekg(file.beg);
//去除第一行,即*.csv文件的表头
do{
file.get(t);
}while(t!='\n');
//去除第一句中的首个"号,如果没有,证明格式错误,或文件为空
file.get(t);
if(t!='\"')
return false;
//读取余下所有内容
std::string s;
while(!file.eof()){
file.get(t);//用get函数可以读取换行等非显示字符,用重载的>>就不行
s.push_back(t);
}
file.close();
//处理读取进来的内容,将\",\"替换为№\n。
std::basic_string <char>::size_type i;
i = s.find("\",\"",0);
while (i != std::string::npos ){
s.replace(i,3,"№\n");
i=s.find("\",\"",i);
}
//将\",\n\"替换为№\n
i = s.find("\",\n\"",0);
while (i != std::string::npos ){
s.replace(i,4,"№\n");
i=s.find("\",\n\"",i);
}
//处理读取进来的内容,将文件末尾的\",,替换为№。
i=s.find_last_of("\",");
s.replace(i-1,2,"№");
//将处理后的内容写入文件
std::fstream out(ofilename.data(),std::ios::out);
if(!out){
//std::cout << "无法创建格式化信息文件" << ofilename << std::endl;
return false;
}
out << s;
return true;
}
bool msgs::saveMsgsToBin(QString filename){
QStringList a;
for(int i=0;i<allMsgs.length();i++){
a.push_back(allMsgs.at(i).message);
a.push_back(allMsgs.at(i).name);
a.push_back(allMsgs.at(i).phoneNo);
a.push_back(allMsgs.at(i).time);
}
QFile file(filename);
if(!file.open(QIODevice::WriteOnly)){
//std::cout << "无法写入程序数据到" << filename.toStdString() << std::endl;
return false;
}
QDataStream out(&file);
out<<a;
file.close();
return true;
}