c++记录一下

自定义协议头。扩展通过协议版本来扩展协议头。

#pragma pack (1)
struct comPrtcV0Head
{
    u8 fixedHead[COMPRTC_FIX_HEAD_LEN];//固定0XC6B796
    u32 datalen;//数据长度
    u8 protocVer;//协议版本
    u8 encodeType;//加密类型
    u8 compressType;//压缩标志
    u16 crc;//求和校验
};
#pragma pack()

右值

class myc
{
public:
    myc()
    {
        logwdbg("myc");
    }
    myc(myc&& ot) noexcept
        : val(ot.val)
    {
        ot.val = 0;
        logwdbg("myc1");
    }
    ~myc()
    {
        logwdbg("~myc");
    }
    int val;
};

myc tmcc;
int main()
{
    logv4OperateClassV2::instance().logv4init();
    int a = 10, b = 20;
    int &&c = a + b;
    int &&rr1 = 10;
    rr1 = 20;
    const int &d = a;
    logwdbg("%p,%p,%p,%p", &a, &b, &c, &d);
    rr1 = std::move(a);
    logwdbg("%d,%d", rr1, a);
    std::string s1 = "123";
    std::string &&s2 = "345";
    logwdbg("%s,%s", s2.c_str(), s1.c_str());
    std::string&& s3 = std::move(s1);
    logwdbg("%s,%s", s3.c_str(), s1.c_str());

    myc tmc;
    tmc.val = 1;
    myc tmpc1 = std::move(tmc);
    tmpc1.val = 2;
    tmc.val = 3;
    logwdbg("%d,%d", tmpc1.val, tmc.val);
    return 0;
}

25.关于多线程类编程;如果类函数正在运行,其他线程释放该类,会导致类数据被释放而出错!

24.总结,项目的一些坑。
a。TCP长连接,HTTP短连接,UDP各有好处,看如何运用。
b。不用FTP来实现文件传输,其实TCP已经能做到连续发送,而FTP没有加密或服务器屏蔽了21端口就很麻烦
c。不用telnet,而移植ssh。主要是因为加密。
d。我们很喜欢json数据,为了防止数据的冗余可以使用如下方式修身:json-压缩-加密-(base64编码)<--->(base64解码)-解密-解压-json。压缩和解压会浪费时间,json太大也费时间。有测试过:PC电脑制作下面格式的JSON,10万条10列的表格,用了2秒左右。

{
    "tableName":{
        "cols":[
            "col1",
            "col2",
            "col3",
            "col4",
            "col5"
        ],
        "rows":[
            [
                "lxin0",
                "surp0",
                "\u5e9f\u4e86",
                "\u5f850",
                "\u98de\u673a"
            ],
            [
                "lxin1",
                "surp1",
                "\u5e9f\u4e86",
                "\u5f851",
                "\u98de\u673a"
            ]
        ]
    }
}

e。protocolbuffer还是要更快。

f.锁包含的内容尽可能短,不要出现锁中还有锁的情况,不然容易出现互锁。

g.libevent读回调,多线程情况下,回调时已经上锁了,所以读取保存,数据放到其他线程处理。防止连环锁。

h.数据,执行任务分离。一个类,经常释放和创建,并且执行任务时间长,释放时可能会出现锁死(如果类添加了锁)或崩溃(没有添加锁,数据被释放,任务又在执行)。

23.c++设计问题,用c++就是为了分配空间和释放空间在内部进行。这样可以尽可能的解决内存泄露(遗忘释放)。所以写类的时候,尽可能的把分配放在class内部,释放时一起释放。

22.undefined reference to xxx问题。明明添加了.so 或.o但是提示该问题。可能是因为g++链接gcc编译的.o文件。需要对gcc编译的头文件进行处理:

extern "C" {

#include "sample_comm.h"

#include "acodec.h"

#include "audio_aac_adp.h"

#include "audio_dl_adp.h"

#include "audio_mp3_adp.h"

}

参考:

g++链接gcc编译的库报错“undefined reference to xxx”

当用extern “c”编译库函数之后,在c++代码中调用时,出现标题错误。
解决方法:
在包含头文件时,告诉编译器这个是c函数。
//假定动态库的头文件为 tools.h
extern “C”{
#include “tools.h”
}
这样在使用g++编译c++代码时,编译动态库中的函数使用C的编译方式。而不会处理函数名导致在库中无法找到函数。

21.静态编译出错问题:参考mysql静态编译_静态编译mysql库到程序中遇到的问题_AslrDep的博客-CSDN博客

g++ -o test.cgi test.cpp -static -lsqlite3 -llog4cplus -ljsoncpp -lpthread -ldl -lm

报错:Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

这个运行时需要动态库,而我程序必须用静态编译。折中:-Wl,-dn跟静态编译..-Wl,-dy接动态编译。

g++ -o test.cgi test.cpp -Wl,-dn -lsqlite3 -llog4cplus -ljsoncpp -Wl,-dy -lpthread -ldl -lm

$(CXX) -o $@ $^ $(COM_SRC) -Wl,-dn $(CFLAGS) $(COMPILE_USR_FLAGS) -lcgicc -Wno-write-strings -ljsoncpp -lsqlite3 -Wl,-dy -lpthread -ldl -lm

20.异常情况

    long tmpval = 0;
    string tmpstr = "";
    tmpval = atol(tmpstr.c_str());
    logwdbg("%d", tmpval);
    try
    {
        tmpval = stol(tmpstr);//对空字符串进行转换。这里会出现异常
    }
    catch(...)
    {
        logwdbg("err");
    }
    logwdbg("%d", tmpval);

note:应用层程序设计模式:

Z1.分模块:

  A控制模块-核心模块;

  B检测状态模块:硬件接口异常。比如网络,串口,I2C通讯,输入信号异常,其他模块工作异常等

  C参数管理模块

  D数据储存模块,如sql数据库,文件操作

  Ehttps通讯模块

  F自定义协议模块

  G其他工作用到的模块

参考手册cppreference.com

1、虚函数占有对象空间,而普通成员函数不会。估计是为了指向子类的函数地址

2、多线程操作同一个容器、迭代器会导致出错,因此加锁。

3、下面代码有问题:条件变量会出现不正常唤醒!!!需要使用lambda来加强控制。 如if (myconvar.wait_for(waitLock, 200 * 1ms, [a]{return *a;})){}。参考std::condition_variable::wait_for - cppreference.com

std::mutex mymutex;
condition_variable myconvar;
atomic_int myatoval = 0;

void threadfunc()
{
    while (1)
    {
        Sleep(50);
        if (myatoval % 5 == 0)
        {
            myconvar.notify_all();
        }
    }
}

void convarWait()
{
    myatoval = (myatoval + 1) % 100;
    int retrycount = 2;
    while (retrycount-- > 0)
    {
        {
            std::unique_lock<std::mutex> waitLock(mymutex);
            if (myconvar.wait_for(waitLock, 200 * 1ms) == cv_status::no_timeout)
            {
                cout << "condition is weakuped! atoval = " << myatoval << endl;
                break;
            }
            else
            {
                cout << "condition timeout! ato = " << myatoval << endl;
            }
        }
    }
}

int main()
{
    thread tmpthread = thread(threadfunc);
    while (1)
    {
        Sleep(10);
        convarWait();
    }
    return 0;
}

4、模板类写在头文件,不要成员函数与类分离写。不然会很麻烦。

5、c++成员函数不能实现每个对象都有空间,需要回调成员函数时,把对象也放到回调的参数中即可。

6、类的构造函数不能是虚函数,是因为我们new一定是子类,会调用父类和子类构造函数。析构函数为虚函数主要应用在指针情况,在释放父类指针就相当于直接释放子类。如果不是虚函数,只会释放父类。如果不是指针情况,释放子类,会调用子类析构和父类析构。

7、字符串流得到4位补0的字符串:需头文件:#include <iomanip>

stringstream strinput;

strinput << setw(4) << setfill('0') << count;

8、c++11才支持to_string,如:

string mys = "hello world!" + to_string(100) + ",finish!";

如果<c++11这样写,或者用stringstream(例7)来处理:

string mys = "hello world!";

mys += 100;

mys += ",finish!";

9、stringstream的坑:

stringstream getcmd;

getcmd << "id1=" << id1<< "sid1=" << id2 << ";";

tmpstr = getcmd.str();//这里还没有问题

getcmd.str("");//如果没有这一句,下面的内容会和上面内容组成一个字符串的。getcmd.clear();也是没有删除流缓存的

getcmd << "id3=" << id3<< "sid4=" << id4 << ";";

tmpstr = getcmd.str();

10、延时,睡眠函数:

 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //单位是毫秒

11.new 错误时不是返回null,而是抛出异常,可以使用:new (std::nothrow)来关闭一场,然后判断null。如:

int* p = new (std::nothrow) int[100000];
if ( p == nullptr ){}

12.cout << 是根据数据类型进行输出的,int输出数字,而char输出字符,如果你要输出char为数字,可以转为int

13.扩展cout,用方法1会出现我要屏蔽打印就想不到更好的办法了,而方法2直接使用空宏定义即可屏蔽

//#define coutdbg cout << "[cxxdbg:" << __func__ << "," << __LINE__ << "]"//方法1

#define coutdbg(fmt) //cout << "[cxxdbg:" << __func__ << "," << __LINE__ << "]" << fmt << endl;//方法二

使用:coutdbg("abc=" << abc);

printf参考:

#define PRINTF_DEF(lev, fmt, lprt, ...) do {\
        if(DEBUG_LEVEL_DEF >= lev) {\
            struct timeb tnow;\
            struct tm *tmnow;\
            ftime(&tnow);\
            tmnow = localtime(&tnow.time);\
            printf("[%d-%d-%d %d:%d:%d.%3d][%s][%s,%d]" fmt "\n", tmnow->tm_year + 1900, tmnow->tm_mon + 1, \
                tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec, tnow.millitm, \
                lprt, __func__, __LINE__, ##__VA_ARGS__);\
        }\
    }while(0);

#define printfdbg(fmt, ...) do {\
            struct timeb tnow;\
            struct tm *tmnow;\
            ftime(&tnow);\
            tmnow = localtime(&tnow.time);\
            printf("[%d-%d-%d %d:%d:%d.%3d][%s,%d]" fmt "\n", tmnow->tm_year + 1900, tmnow->tm_mon + 1, \
                tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec, tnow.millitm, \
                __func__, __LINE__, ##__VA_ARGS__);\
    }while(0);

cout参考:

#define cout_base(lev, fmt) do {\
        if(DEBUG_LEVEL_DEF >= lev) {\
            struct timeb tnow;\
            struct tm *tmnow;\
            ftime(&tnow);\
            tmnow = localtime(&tnow.time);\
            cout << "[" << tmnow->tm_year + 1900 << "-" << tmnow->tm_mon + 1 << "-" << tmnow->tm_mday \
                << " " << tmnow->tm_hour << ":" << tmnow->tm_min << ":" << tmnow->tm_sec << "." \
                << setw(3) << setfill('0') << tnow.millitm << "]" << fmt << endl;\
        }\
    }while(0);

14.高内聚低耦合:高内聚低耦合_百度百科

15.boost 的json:参考 boost json生成和解析用法 - doutu - 博客园

--> boost json不支持空数组,在本例中空数组对应的格式为"列表":"";

--> 空的字符串字段转换为数字会抛异常。

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <sys/timeb.h>
#include <vector>
#include <iostream>
using namespace boost::property_tree;
using namespace std;

#define cout_base(lev, fmt)                                                                           \
	do                                                                                                \
	{                                                                                                 \
		if (4 >= lev)                                                                                 \
		{                                                                                             \
			struct timeb tnow;                                                                        \
			struct tm *tmnow;                                                                         \
			ftime(&tnow);                                                                             \
			tmnow = localtime(&tnow.time);                                                            \
			cout << "[" << tmnow->tm_year + 1900 << "-" << tmnow->tm_mon + 1 << "-" << tmnow->tm_mday \
				 << " " << tmnow->tm_hour << ":" << tmnow->tm_min << ":" << tmnow->tm_sec << "."      \
				 << setw(3) << setfill('0') << tnow.millitm << "]" << fmt << endl;                    \
		}                                                                                             \
	} while (0);
#define coutdbg(fmt) cout_base(4, "dbg[" << __func__ << "," << __LINE__ << "]" << fmt)

#define MY_ROW_NUMBER 20
bool CreateJson(string &str)
{
	stringstream tmpstream;
	int i;
	try
	{
		ptree boot;
		boot.put<string>("table", "人物表格");
		boot.put<string>("rows", to_string(MY_ROW_NUMBER));
		ptree rowlist;
		ptree columnList;
		for (i = 0; i < MY_ROW_NUMBER; i++)
		{
			columnList.clear();
			columnList.put<string>("name", "sheng-" + to_string(i));
			columnList.put<int>("体重", rand() % 1000);
			columnList.put<string>("升高", to_string(random() % 1000));
			columnList.put<string>("外号", "外号" + to_string(i));
			rowlist.push_back(ptree::value_type("", columnList));
		}
		boot.put_child("列表", rowlist);
		write_json(tmpstream, boot);
	}
	catch (ptree_error e)
	{
		coutdbg(e.what());
		return false;
	}
	str = tmpstream.str();
	cout << str << endl;
	return true;
}

struct peopleinformDef
{
	string name;
	int height;
	int weight;
	string uname;
};

bool ParseJson(string &str)
{
	try
	{
		ptree boot;
		stringstream tmpstream(str);
		read_json(tmpstream, boot);
		if (boot.find("体重") != boot.not_found())
		{
			coutdbg(boot.get<string>("table"));
			coutdbg(boot.get<string>("rows"));
		}
		else
		{
			coutdbg("err");
		}
		ptree plist = boot.get_child("列表");
		vector<peopleinformDef> pilist;
		BOOST_FOREACH (auto val, plist)
		{
			peopleinformDef tmpif;
			tmpif.name = val.second.get<string>("name");
			tmpif.weight = val.second.get<int>("体重");//atof(val.second.get<string>("体重").c_str());
			tmpif.height = atof(val.second.get<string>("升高").c_str());
			tmpif.uname = val.second.get<string>("外号");
			pilist.push_back(tmpif);
		}
		for (int i = 0; i < pilist.size(); i++)
		{
			coutdbg(pilist[i].name << "|" << pilist[i].weight << "|" << pilist[i].height << "|" << pilist[i].uname);
		}
	}
	catch (ptree_error pt)
	{
		coutdbg(pt.what());
		return false;
	}
	return true;
}
int main(int argc, char *argv[])
{
	string tmpstr;
	CreateJson(tmpstr);
	ParseJson(tmpstr);
	return 0;
}

16.jsoncpp,我们去json-cpp download | SourceForge.net下载源码,编译我们只需要:json(头文件夹)  json_reader.cpp  json_tool.h  json_value.cpp  json_valueiterator.inl  json_writer.cpp  Makefile文件即可编译,自己写makefile。测试代码:其中root["错误的名字"].asString()不会异常,比boost好一些拉!

#include <types.h>
#include <json/json.h>
void writeToJsonStr(string &outjson)
{
    Json::Value root;
    root["rootflag"] = Json::Value(1);
    root["rootname"] = Json::Value("root");
    Json::Value rootinf;
    rootinf["childNumber"] = Json::Value(2);
    rootinf["age"] = Json::Value(33);
    rootinf["favor"] = Json::Value("lxin");
    root["inform"] = rootinf;
    for (int i = 0; i < 2; i++)
    {
        Json::Value child;
        child["name"] = Json::Value("child" + to_string(i));
        child["age"] = Json::Value(i + 10);
        child["sex"] = Json::Value(i % 2);
        root["childs"].append(child);
    }
    for (int i = 0; i < 5; i++)
    {
        root["gospace"].append("place_" + to_string(i));
    }
    //直接输出
    cout << "FastWriter:" << endl;
    Json::FastWriter fw;
    cout << fw.write(root) << endl
         << endl;

    //缩进输出
    cout << "StyledWriter:" << endl;
    Json::StyledWriter sw;
    cout << sw.write(root) << endl
         << endl;
    outjson = sw.write(root);
}

void parseJsonStr(string injson)
{
    Json::Reader tmpreader;
    Json::Value root;
    if (!tmpreader.parse(injson, root))
    {
        couterr("err");
    }
    Json::FastWriter fw;
    cout << fw.write(root) << endl;
    coutdbg(root["rootname"].asString());
    coutdbg(root.isMember("noname") << "," << root.isMember("rootname"));
    coutdbg(root["childs"].isArray() << "," << root["gospace"].isArray());
    for (auto a = root.begin(); a != root.end(); a++)
    {
        printfdbg("key=%s,type=%d", a.memberName(), a->type());
        if (a->type() == Json::arrayValue)
        {
            for (auto b = a->begin(); b != a->end(); b++)
            {
                printfdbg("key=%s,type=%d", b.memberName(), b->type());
            }
        }
    }
}

int main()
{
    string tmpstr;
    writeToJsonStr(tmpstr);
    parseJsonStr(tmpstr);
}

17.json传输二进制数据参考:把二进制数据压缩后使用Base64编码(每6bit组成一个字符,数据大1/3,比2倍好吧)为字符串。接收到数据时解码解压即可

18.zlib库:Index of /fossils

编译:cd $(OPENSOURCE_LIB_BUILD_PWD) && export gcc=$(CROSS_COMPILE)-gcc && ./configure --prefix=$(OPENSOURCE_INSTALL_PWD) && make clean && make && make install

使用需注意的地方:

1.压缩数组如果是随即数组,压缩效果低,甚至比原属组还大一点。

2.数组小压缩率低

3.压缩时可以用compressBound来获得最大的压缩后的长度

4.解压数组长度我们不好确定,个人觉得使用固定大小,与压缩前的进行协商最大值即可。

#include <types.h>
#include <ctimer.h>
#include <json/json.h>
#include <base64.h>
#include <zlib.h>

void printstrbuf(string sin)
{
    coutdbg("the string len is : " << sin.length());
    for (int i = 0; i < (int)sin.length(); i++)
    {
        printf("%02X ", (u8)sin[i]);
        if (i % 16 == 15)
        {
            printf("\n");
        }
    }
    printf("\n");
}

int mycompress(string in, string &out, int level = 9)
{
    Bytef *tmpcomp;
    uLong tmpcompLen;
    int comperr;
    tmpcompLen = compressBound(in.length());
    tmpcomp = newwork Bytef[tmpcompLen];
    out.clear();
    if (!tmpcomp)
    {
        couterr("err");
        return -10;
    }
    //comperr = compress(tmpcomp, &tmpcompLen, (const Bytef*)in.c_str(), in.length());
    comperr = compress2(tmpcomp, &tmpcompLen, (const Bytef *)in.c_str(), in.length(), level);
    if (comperr != Z_OK)
    {
        printferr("err:%d", comperr);
        goto freeOut;
    }
    out.append((char *)tmpcomp, tmpcompLen);
freeOut:
    delete[] tmpcomp;
    return comperr;
}

int myumcompress(string in, string &out)
{
    Bytef *tmpuncomp;
    uLong tmpuncompLen;
    int comperr;
    tmpuncompLen = 10 * 1024 * 1024; //use fixed uncompress max len = 10M, in.length() * 30;
    tmpuncomp = newwork Bytef[tmpuncompLen];
    out.clear();
    if (!tmpuncomp)
    {
        couterr("err");
        return -10;
    }
    //comperr = uncompress(tmpuncomp, &tmpuncompLen, (const Bytef*)in.c_str(), in.length());
    uLong inlen = in.length();
    comperr = uncompress2(tmpuncomp, &tmpuncompLen, (const Bytef *)in.c_str(), &inlen);
    if (comperr != Z_OK)
    {
        printferr("err:%d", comperr);
        goto freeOut;
    }
    out.append((char *)tmpuncomp, tmpuncompLen);
freeOut:
    delete[] tmpuncomp;
    return comperr;
}

// string getPhotoStr(void)
// {
//     string tmps, tmpsout;
//     for (int i = 0; i < 1024; i++)
//     {
//         tmps += rand() % 256;
//     }
//     base64Encode(tmps, tmpsout);
//     return tmpsout;
// }

string getPhotoStr(void)
{
    string tmps, tmpsout;
    for (int i = 0; i < 1024; i++)
    {
        tmps += i % 256;
    }
    base64Encode(tmps, tmpsout);
    return tmpsout;
}

void getJsonStr(string &outjson, int arraylen)
{
    Json::Value root;
    root["table"] = Json::Value("testtable");
    for (int i = 0; i < arraylen; i++)
    {
        Json::Value child;
        child["name"] = Json::Value("childmy" + to_string(i));
        child["age"] = Json::Value(i + 10);
        child["sex"] = Json::Value(i % 2);
        child["addr"] = Json::Value("中南达到123345中国" + to_string(i));
        child["photo"] = Json::Value(getPhotoStr());
        root["childs"].append(child);
    }
    // for (int i = 0; i < 5; i++)
    // {
    //     root["gospace"].append("place_" + to_string(i));
    // }
    // //直接输出
    // cout << "FastWriter:" << endl;
    Json::FastWriter sw;
    // cout << fw.write(root) << endl
    //      << endl;
    //缩进输出
    //cout << "StyledWriter:" << endl;
    //Json::StyledWriter sw;
    // cout << sw.write(root) << endl
    //      << endl;

    outjson = sw.write(root);
}

void parseJson(string jsonstr)
{
    Json::Reader tmpreader;
    Json::Value root;
    if (!tmpreader.parse(jsonstr, root))
    {
        couterr("err");
        return;
    }
    coutdbg(root["table"].asString());
    coutdbg(root["childs"].size())
}

int main()
{
    string strorigin, strencode, strdecode;
    int compressCout = 1;
    coutdbg("test rand value!");
    timerc myt;
    while (compressCout++ < 5000)
    {
        strorigin.clear();
        for (int i = 0; i < compressCout; i++)
        {
            strorigin += rand() % 256;
        }
        if (mycompress(strorigin, strencode))
        {
            break;
        }
        //printfdbg("compress: %lu->%lu", strorigin.length(), strencode.length());
        if (myumcompress(strencode, strdecode))
        {
            break;
        }
        //printfdbg("uncompress: %lu->%lu", strencode.length(), strdecode.length());
        if (strdecode.compare(strorigin) != 0)
        {
            couterr("err");
            printstrbuf(strorigin);
            printstrbuf(strdecode);
        }
    }
    coutdbg("used time:" << myt.ints());
    myt.begin();
    for (compressCout = 1; compressCout < 500; compressCout++)
    {
        getJsonStr(strorigin, compressCout);
        if (mycompress(strorigin, strencode))
        {
            break;
        }
        //printfdbg("compress: %lu->%lu", strorigin.length(), strencode.length());
        if (myumcompress(strencode, strdecode))
        {
            break;
        }
        printfdbg("count=%d, uncompress: %lu->%lu", compressCout, strencode.length(), strdecode.length());
        if (strdecode.compare(strorigin) != 0)
        {
            couterr("err");
            printstrbuf(strorigin);
            printstrbuf(strdecode);
        }
        parseJson(strdecode);
    }
    coutdbg("used time:" << myt.ints());
}

json传输二进制的方案_xingty的博客-CSDN博客_json 二进制

19. 如果父类析构函数为虚函数,释放父类对象,会先调用子类的析构函数,再释放父类!如果不是,则只释放父类。

20. new一个结构体: myinfo *abc = new myinfo;和myinfo *abc = new myinfo();是有差异的,加了()后,初始化为0!

21.base64参考:根据java.util.Base64中Base64.getEncoder().encode和Base64.getDecoder().decode样例。

备注:java.util.Base64中还有getUrlEncoder(特殊字节不是+/而是-_)和getMimeEncoder(74字节添加\r\n)

编解码与网页保持一致:Base64 编码/解码 | 菜鸟工具

#ifndef __BASE64_ENC_DEC_H__
#define __BASE64_ENC_DEC_H__
#include <types.h>

class base64Class
{
public:
    static string Encode(const unsigned char *Data, int DataByte)
    {
        if(!Data)
        {
            return "";
        }
        //编码表
        const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        //返回值
        string strEncode;
        unsigned char Tmp[4] = {0};
        // int LineLength = 0;
        for (int i = 0; i < (int)(DataByte / 3); i++)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            Tmp[3] = *Data++;
            strEncode += EncodeTable[Tmp[1] >> 2];
            strEncode += EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F];
            strEncode += EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F];
            strEncode += EncodeTable[Tmp[3] & 0x3F];
            // if(LineLength+=4,LineLength==76) {strEncode+="\r\n";LineLength=0;}
        }
        //对剩余数据进行编码
        int Mod = DataByte % 3;
        if (Mod == 1)
        {
            Tmp[1] = *Data++;
            strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode += EncodeTable[((Tmp[1] & 0x03) << 4)];
            strEncode += "==";
        }
        else if (Mod == 2)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode += EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)];
            strEncode += EncodeTable[((Tmp[2] & 0x0F) << 2)];
            strEncode += "=";
        }

        return strEncode;
    }

    static string Decode(const unsigned char *Data, int DataByte)
    {
        if(!Data)
        {
            return "";
        }
        char const DecodeTable[256] =
        {
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0X3E,(char)0XFF,(char)0XFF,(char)0XFF,(char)0X3F,
            (char)0X34,(char)0X35,(char)0X36,(char)0X37,(char)0X38,(char)0X39,(char)0X3A,(char)0X3B,
            (char)0X3C,(char)0X3D,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0X00,(char)0X01,(char)0X02,(char)0X03,(char)0X04,(char)0X05,(char)0X06,
            (char)0X07,(char)0X08,(char)0X09,(char)0X0A,(char)0X0B,(char)0X0C,(char)0X0D,(char)0X0E,
            (char)0X0F,(char)0X10,(char)0X11,(char)0X12,(char)0X13,(char)0X14,(char)0X15,(char)0X16,
            (char)0X17,(char)0X18,(char)0X19,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0X1A,(char)0X1B,(char)0X1C,(char)0X1D,(char)0X1E,(char)0X1F,(char)0X20,
            (char)0X21,(char)0X22,(char)0X23,(char)0X24,(char)0X25,(char)0X26,(char)0X27,(char)0X28,
            (char)0X29,(char)0X2A,(char)0X2B,(char)0X2C,(char)0X2D,(char)0X2E,(char)0X2F,(char)0X30,
            (char)0X31,(char)0X32,(char)0X33,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
            (char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,(char)0XFF,
        };
        //返回值
        string strDecode;
        int nValue;
        int i = 0;
        DataByte = DataByte / 4 * 4;
        while (i < DataByte)
        {
            if (*Data != '\r' && *Data != '\n')
            {
                nValue = DecodeTable[*Data++] << 18;
                nValue += DecodeTable[*Data++] << 12;
                strDecode += (nValue & 0x00FF0000) >> 16;
                if (*Data != '=')
                {
                    nValue += DecodeTable[*Data++] << 6;
                    strDecode += (nValue & 0x0000FF00) >> 8;
                    if (*Data != '=')
                    {
                        nValue += DecodeTable[*Data++];
                        strDecode += nValue & 0x000000FF;
                    }
                }
                i += 4;
            }
            else // 回车换行,跳过
            {
                Data++;
                i++;
            }
        }
        return strDecode;
    }
};
#endif

22.做字符串分割:

std::vector<std::string> splitStrWithPat(const std::string &str, const std::string pattern)
{
    std::vector<std::string> ret;
    if (pattern.empty())
    {
        return ret;
    }
    size_t start = 0, index = str.find_first_of(pattern, 0);
    while (index != str.npos)
    {
        if (start != index)
        {
            ret.push_back(str.substr(start, index - start));
        }
        start = index + pattern.length();
        index = str.find_first_of(pattern, start);
    }
    if (!str.substr(start).empty())
    {
        ret.push_back(str.substr(start));
    }
    return ret;
}

std::string linkStrWithPat(const std::vector<std::string> &vecstr, const std::string pat)
{
    std::string ret;
    for (size_t i = 0; i < vecstr.size(); i++)
    {
        ret.append(vecstr[i]);
        if (i < vecstr.size() - 1)
        {
            ret.append(pat);
        }
    }
    return ret;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值