64,654
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
using namespace std;
class A
{
public:
int i;
double d;
char* c;
string s;
int print(); // 按照配置文件中定义的顺序打印
};
/*
* 我想在配置文件中定义输出变量及其顺序,比如:
* format=${i}|${s}|${d}|
* 注意:某些变量${c}没有出现在配置里,表示不打印。
*/
LOAD_CONFIG(); // 加载配置
A a;
a.print(); // 按照配置文件中定义的顺序打印
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class A
{
public:
int i;
double d;
char* c;
string s;
void print(char* config) // 按照配置文件中定义的顺序打印
{
while(strlen(config) > 0)
{
if(*config == 'i')
{
cout << i << " ";
}
if(*config == 'd')
{
cout << d << " ";
}
if(*config == 'c')
{
cout << c << " ";
}
if(*config == 's')
{
cout << s << " ";
}
config++;
}
cout << endl;
}
};
int main(int argc, char* argv[])
{
char config[100] = {0};
// 从文件读出数据
ifstream fis("E:/config.dat");
if(!fis)
{
cout << "can not open file..." << endl;
exit(1);
}
fis.getline(config, 100);
fis.close();
A a = {1, 2.2, 0, "hello"};
a.print(config);
return 0;
}
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
enum ItemType
{
TYPE_INT,
TYPE_DOUBLE,
TYPE_STLSTRING,
};
struct ItemFormat
{
const char *name; // 变量名
ItemType tp; // 变量类型
const char *fmt; // 格式化符号
size_t offset; // 类型偏移
};
class A
{
public:
int i;
double d;
std::string s;
static int SetFormat(const char* fmt);
int printfA(char* buff, int bufflen, ItemFormat *fmt, int sz);
};
//
// 所有可用的配置变量
//
ItemFormat g_ItemFormat[] = {
{"i", TYPE_INT, "%d", &A::i},
{"s", TYPE_STLSTRING, "%s", &A::s},
{"d", TYPE_DOUBLE, "%f", &A::d},
};
#define PREFIX '$'
//
// format=hello|${i}|${s}|${d}|world
//
static char g_fmt[1024] = {0}; // 加载上述配置后变成:hello|$|$|$|world
static std::vector<int> g_ItemOrder; // 加载上述配置后变成:[0,1,2], 数字分别表示上述 $ 符号对应在 g_ItemFormat 里的下标
//
// 格式配置加载、转换由 SetFormat 完成
//
int A::SetFormat(const char* fmt)
{
int i = 0;
for(i=0; (i<sizeof(g_fmt)) && (0!=fmt[i]); i++)
{
g_fmt[i] = fmt[i];
if(PREFIX==fmt[i]) // xxxx${varname}zzzz
{
++i;
if( (i<sizeof(g_fmt)) && ('{'==fmt[i]) )
{
++i; // begin pos of 'varname'
char varname[32] = {0};
int j = 0;
for(j=0; (j<sizeof(varname)) && (0!=fmt[i]) && ('}'!=fmt[i]); j++)
{
varname[j] = fmt[i];
++i;
}
if('}'!=fmt[i]) // 最后的字符必定是'}', 否则格式有误
return -1;
int itemid = -1;
// 找到该变量在 g_ItemFormat 中的位置
for(j=0; j<sizeof(g_ItemFormat)/sizeof(ItemFormat); j++)
{
if( 0==strcmp(g_ItemFormat[j].name, varname) )
{
itemid = j;
break;
}
}
if(itemid>=0)
g_ItemOrder.push_back(itemid);
}
}
}
return 0;
}
int A::printfA(char* buff, int bufflen, ItemFormat *fmt, int sz)
{
char *p = buff;
int i = 0;
std::vector<int>::const_iterator it = g_ItemOrder.begin();
for(i=0; ((i<sizeof(g_fmt)) && (0!=g_fmt[i]) && (p-buff)<sizeof(buff)); i++)
{
if( PREFIX==g_fmt[i] )
{
if(it!=g_ItemOrder.end())
{
int len = 0;
int idx = *it;
if( idx>=0 && idx<=sz && NULL!=fmt[idx].name )
{
switch(fmt[idx].tp)
{
case TYPE_INT:
len = sprintf(p, fmt[idx].fmt, *((int*)((void*)this+fmt[idx].offset)));
break;
case TYPE_DOUBLE:
len = sprintf(p, fmt[idx].fmt, *((double*)((void*)this+fmt[idx].offset)));
break;
case TYPE_STLSTRING:
len = sprintf(p, fmt[idx].fmt, (std::string*)((void*)this+fmt[idx].offset)->c_str());
break;
default:
break;
}
if( len>0 )
{
p += len;
}
else // failed when do sprintf
{
memset(buff, 0, bufflen);
return -1;
}
}
else
{
return -1;
}
it++;
}
else
{// $, 但是没有格式化信息,即 $ 的数量太多
memset(buff, 0, sizeof(buff));
return -1;
}
}
else
{
*p = g_fmt[i];
++p;
}
}
if((0!=g_fmt[i]) || (p-buff)>sizeof(buff))
{
memset(buff, 0, sizeof(buff));
return -1;
}
return 0;
}
int main(int argc, char* argv[])
{
A::SetFormat("hello|${i}|${s}|${d}|world");
A a;
a.i = 1;
a.s = "s";
a.d = 3.1415;
char buff[1024] = {0};
a.printfA(buff, 1024, g_ItemFormat, sizeof(g_ItemFormat)/sizeof(ItemFormat));
cout << buff << endl;
}
ItemFormat itfmt[] = {
{"i", TYPE_STLSTRING, "%d", &A::i, 0},
{"c", TYPE_STLSTRING, "%s", &A::c, 0},
{"d", TYPE_UINT32, "%d", &A::d, 0},
{"s", TYPE_STLSTRING, "%s", &A::s, 0},
{0, 0, 0, 0}
};