实现占位符替换接口,同printf

导航语音实现方案(文尾附有源码)

函数接口如下

 

char *textTranslate(char *content, …)

 

content:可变参列表中的固定参,包含占位符的字符串;

…:可变参数;

返回值:为替换后的字符串

使用时将占位符所代表的值解析后,按照content中占位符顺序依次传递给可变参数列表,函数即可返回content所代表的实际内容,用法同printf(char*, …);

结合配置文件,实现可配置语音组合模式

占位符定义

  • 1 占位符定义

定义

含义

备注

@i

整形数据

代表所有int型数据,最大为int取值范围,可表示距离/角度等

@s

字符型数据

字符串,char*

如“前方100米上坡”

content表示为:

  • 2 “前方100米上坡”的通用述方式

前方

@i

@s

 

 

函数接口与配置文件

配合配置文件可实现语音组合的来灵活配置,配置文件配置示例如下:

 

[导航语音]

beginNavi = “开始导航,向北偏南@i度方向出发,全程共@i米”

distanceNotice = “当前已行使@i米,还剩@i米完成本次机动任务”

keyPoint1 = “前方@i米路口@s”

[关键点类型]

key1 = “左转”

key2 = “右转”

key3 = “左调头”

.

.

 [桅杆告警]

mastWarning = “桅杆升起,请勿行车”

[偏航告警]

yawWarning = “您已偏离预定航线”

 

函数使用举例如下:

如播报配置文件中设置的开始导航语音条目:

beginNavi = “开始导航,向北偏南@a度方向出发,全程共@i米”时,调用方式如下:

beginNavi = textTranslate(beginNavi, 30, 100);

该函数将@a替换为30,@i替换为100,替换后的结果为:

beginNavi = “开始导航,向北偏南30度方向出发,全程共100米”

开发者只需要从配置文件中选择自己需要的条目,并将对应的数值传递按照顺序传递给textTranslate函数即可。

函数实现

Algorithm.h

#ifndef ALGORITHM_H
#define ALGORITHM_H

class Algorithm
{
public:
    Algorithm();
    char *textTranslate(char *format,...);//数字不能以0开头
private:
    char *replaceHolder(char *&str, char *replace, int pos);
    char *intToChar(int val);
};

#endif // ALGORITHM_H

Algorithm.cpp

#include "Algorithm.h"
#include <stdio.h>
#include<iostream>
#include<string.h>
#include<stdarg.h>

Algorithm::Algorithm()
{

}

char *Algorithm::replaceHolder(char *&str, char* replace ,int pos)
{
    if(str == nullptr)
        return nullptr;
    int lenTotal = strlen(str);
    int lenReplace;
    if(!replace)
        lenReplace = 0;
    else
        lenReplace = strlen(replace);
    int lenTail = lenTotal - pos - 2;
    char *strTotal = new char[lenTotal + lenReplace - 2 + 1];
    char *strTail = new char[lenTail];
    memcpy(strTail, str + pos + 2, lenTail);

    memcpy(strTotal, str, lenTotal);
    memcpy(strTotal + pos, replace, lenReplace);
    memcpy(strTotal + pos + lenReplace, strTail, lenTail);
    memcpy(strTotal + pos + lenReplace + lenTail, "\0",1);
    delete[] strTail;
    return strTotal;
}

char *Algorithm::textTranslate(char *format,...)
{
    va_list ap;
    char *p;
    int ival;
    char *s;
    if(!format)
    {
        return nullptr;
    }
    va_start(ap,format);

    int i = 0, j = 0;
    loop:
    for(i = j, p = format + i; *p; ++i, ++p)
       {
           if(*p != '@')
           {
               continue;
           }
           switch(*++p)
           {
               case 'i'://整形数据
                   ival = va_arg(ap,int);
                   s = intToChar(ival);
                   format = replaceHolder(format, s, i);
                   j = i + 1;
                   goto loop;
                   break;
               case 's'://字符数据
                   s = va_arg(ap,char *);
                   format = replaceHolder(format,s,i);
                   j = i + 1;
                   goto loop;
                   break;
               default:
                   break;
           }
       }
       va_end(ap);
       return format;
}

char *Algorithm::intToChar(int val)
{
    char *str = nullptr;
    int count = 0;
    int localValue = val;
    while(val%10 > 0)
    {
        count++;
        val = val/10;
    }
    str = new char[count];
    _itoa(localValue, str, 10);
    return str;
}

调用测试

main .cpp

#include <QCoreApplication>
#include "algorithm.h"

#ifdef WINDOWS
#include<windows.h>
#endif

#ifdef UNIX
#include<sys\timeb.h>
#endif
#include<iostream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

#ifdef WINDOWS
    DWORD tStart, tEnd;
    tStart = GetTickCount();
#endif
    Algorithm alg;
    char *tempp="hello @s hello @s!\n@i\n@i";
    char *aaa = alg.textTranslate(tempp,"world","windows",100,30);
    cout<<"aaa="<< aaa<<endl;

#ifdef WINDOWS
    tEnd = GetTickCount();
    DWORD tPeriod = tEnd - tStart;
    cout << "tStart=" << tStart << endl;
    cout<< "tEnd=" << tEnd << endl;
    cout << "period=" <<tPeriod<<endl;
#endif

    return a.exec();
}

输出结果:

aaa=hello world hello windows!

100

30

tStart=259596406

tEnd=259596406

period=0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章