使用C++文件流库fstream,读写操作十六进制文本文件

最近为智能移动小车编写上位机软件的过程中,遇到了文件读写处理的任务,文件是一般的文本文件.txt格式的,其内容由十六进制数据组成。文件内数据的格式如下:

FF FD 03 FD 77 FE 77 1C 27

FF FD 01 FE 00 FE 00 1E 28

FF FE 00 FE B4 FE B4 21 28

...

每一帧数据由9个十六进制数据组成,用于标识智能车运行过程的相对于参考轨迹的姿态偏差,以及运行过程的线速度与角速度值。

data[0]: 帧头,由FF标识(实际操作过程数据帧头并未使用到);

data[1],data[2]: 第一个有效数据,位置偏差aglErrdata[1]标识aglErr的符号,data[2]表示aglErr的数值;data[3],data[4]: 第二个有效数据,位置偏差xErrdata[3]标识xErr的符号,data[4]表示xErr的数值;data[5],data[6]: 第三个有效数据,航向角偏差yErrdata[5]标识yErr的符号,data[6]表示yErr的数值;

data[7]: 第四个有效数据,表示智能车实时线速度lineVct,显然为正值;

data[8]: 第五个有效数据,表示智能车实时角速度aglVct显然也为正值


首先,需要把文本文件中的数据读出来并保存在内存中,我使用的数据类型是vector<stirng>,代码如下:

void readFileToRawDatas(const char *p, std::vector<std::string> &m_rawDatas)
{
    std::ifstream dataFile(p);
    if (dataFile)
    {
        std::string str;
        while (dataFile >> str)
            m_rawDatas.push_back(str);
    }
    else
    {
        qDebug() << "Open file failed!";
    }
}

其中,readFileToRawDatas函数接受两个参数,第一个参数是要读取文件的路径,第二个参数是数据存储的目的位置


然后,将字符串类型的十六进制数据转换为int型数据,可以由以下两个函数来实现:

int hexCharToNum(const char c);  将单个字符('A'('a')-'F'('f'))转换为对应的0-15范围内的数字

int hexCharToNum(const char c)
{
	int temp;
	switch (c)
	{
	case '0':
		temp = 0;
		break;
	case '1':
		temp = 1;
		break;
	case '2':
		temp = 2;
		break;
	case '3':
		temp = 3;
		break;
	case '4':
		temp = 4;
		break;
	case '5':
		temp = 5;
		break;
	case '6':
		temp = 6;
		break;
	case '7':
		temp = 7;
		break;
	case '8':
		temp = 8;
		break;
	case '9':
		temp = 9;
		break;
	case 'A':
	case 'a':
		temp = 10;
		break;
	case 'B':
	case 'b':
		temp = 11;
		break;
	case 'C':
	case 'c':
		temp = 12;
		break;
	case 'D':
	case 'd':
		temp = 13;
		break;
	case 'E':
	case 'e':
		temp = 14;
		break;
	case 'F':
	case 'f':
		temp = 15;
		break;
	default:
		break;
	}

	return temp;
}

int hexStrToInt(const string &str);   将两个字符组成的十六进制字符串转换为对应的int型数据

int hexStrToInt(const string &str)
{
	int highBit = 0;
	char lowBit = 0;

	highBit = hexCharToNum(str[0]);
	lowBit = hexCharToNum(str[1]);

	return lowBit + 16 * highBit;
}

最后,实现数据的分类存储

void dataAssort(const std::vector<std::string> &strVec)
{
    int temp = 0;
    for (auto iter = strVec.cbegin(); iter != strVec.cend(); iter += DATA_FRAME_BYTE)
    {
        //设置aglErrDatas
        if ("FE" == *(iter + 1))
        {
            temp = hexStrToInt(*(iter + 2));
            m_aglErrDatas.push_back(temp);
        }
        else
        {
            temp = -1 * hexStrToInt(*(iter + 2));
            m_aglErrDatas.push_back(temp);
        }

        //设置xErrDatas
        if ("FE" == *(iter + 3))
        {
            temp = hexStrToInt(*(iter + 4));
            m_xErrDatas.push_back(temp);
        }
        else
        {
            temp = -1 * hexStrToInt(*(iter + 4));
            m_xErrDatas.push_back(temp);
        }

        //设置yErrDatas
        if ("FE" == *(iter + 5))
        {
            temp = hexStrToInt(*(iter + 6));
            m_yErrDatas.push_back(temp);
        }
        else
        {
            temp = -1 * hexStrToInt(*(iter + 6));
            m_yErrDatas.push_back(temp);
        }

        //设置lineVecDatas
        temp = hexStrToInt(*(iter + 7));
        m_lineVecDatas.push_back(temp);

        //设置aglVecDatas
        temp = hexStrToInt(*(iter + 8));
        m_aglVecDatas.push_back(temp);
    }
}

其中,DATA_FRAME_BYTE表示一帧数据的字节数,即数字9

m_aglErrDatas~m_aglVecDatas是已经定义过的vector<int>对象,即上文我们所说的5个有效数据


最后,放一张离线环境下,通过读取保存在文本文件中原始数据所绘制的智能车位姿以及速度值的波形图,如下:

            

其中,界面是用基于Qt框架所搭建,坐标系图形库采用qcustomplot


  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值