自定义结构体被Format调用的问题

fliplion 2009-11-02 02:42:54
typedef struct tagStruct MYStruct;
struct tagStruct
{
int intValue;
char* chValue;
...
};

MYStruct ms;
CString testStr;
testStr.Format("%s",ms);

预想的目标是在上面的代码中将字符format出来,前提是不修改Format语句,即不是用Format("%s",(char*)ms);方法来实现,想通过修改结构本身实现来完成;

跟踪CString.Format,发现最终用va_arg(*pargptr, int);获取对应值的,如何修改结构实现,让va_arg传出正确的值?
...全文
100 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hdqqq 2009-11-21
  • 打赏
  • 举报
回复
上面的函数把int成员放在前面,程序就崩溃可,而用下面的代码,是可以的.
struct MYStruct
{
int intValue;
char* chValue;

operator char*()
{
static CString ret;
ret.Format("%s %d", chValue, intValue);
return ret.GetBuffer();
}

} ;

void out(const char* info)
{
std::cout << info << std::endl;
}

void test()
{
MYStruct ls;
ls.chValue = "hello world";
ls.intValue = 100;
//CString info;
//info.Format("%s", ls);
out(ls);
}

关键是CString::Format是的变参函数,它通过
va_start( argList, pszFormat )函数,根据格式字符串,确认压栈的参数类型,
然后在_output(outfile,format,ap )函数中(argList 同 ap), 根据ap的值,解析
压入栈的参数,而output能识别的, 是 FL_WIDECHAR,FL_LONG,FL_I64 之类的预定义值,对应 %d, %s等
格式,所以,除非你发明 %to%s 这种格式符号,并改写 va_start,output等crt的实现,
否则,你只能在Format("%s", (char*)ls)中做强转,因为转换必须在压栈前进行,
或者象上面那样用固定长度参数函数.
hdqqq 2009-11-21
  • 打赏
  • 举报
回复
我帮你写算了
实现一个 char* 的操作符重载就可以了,下面的代码在vs2003下帮助通过.
实现操作符重载后, 编译器在调用Format的时候,自动尝试进行转换.
程序输出hello world

typedef struct tagStruct
{
char* chValue;
int intValue;

operator char*()
{
CString ret;
ret.Format("%s %d", chValue, intValue);
return ret.GetBuffer();
}
} MYStruct;

void test()
{
MYStruct ls;
ls.chValue = "hello world";
CString info;
info.Format("%s", ls);
std::cout << info << std::endl;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
test();
// TODO: 在此处为应用程序的行为编写代码。
}

return nRetCode;
}

oyljerry 2009-11-02
  • 打赏
  • 举报
回复
既然想有自定义的Format,那么就不应该改变公用的,而是实现自己定义的对应函数来给自己用..
hdqqq 2009-11-02
  • 打赏
  • 举报
回复
可以对tagStruct 做操作符重载, 实现 char * 操作符.

operator char*()
{
//你的实现.
}
WuXinyang 2009-11-02
  • 打赏
  • 举报
回复
为什么要这样用呢?
ToperRay 2009-11-02
  • 打赏
  • 举报
回复
你在struct tagStruct 里面先格式化一遍,然后再调用

MYStruct ms;
ms.chValue = "aaaaaaaaaaaaaa";
CString testStr;
testStr.Format("%s",ms.Format());

Wenxy1 2009-11-02
  • 打赏
  • 举报
回复
BTW. 你的需求很变态。
希望不要用在现实的项目中,下次不要给人家出这样的笔记题,我个人是很痛恨这种变态而不实用的考题。
Wenxy1 2009-11-02
  • 打赏
  • 举报
回复
继承CString, 重写format成员函数。注意C++变参 ... 的处理。
  • 打赏
  • 举报
回复
如果只是输出chValue的话

typedef struct tagStruct
{
char* chValue;
int intValue;
} MYStruct;


int main()
{
MYStruct ms;
ms.chValue = "aaaaaaaaaaaaaa";
CString testStr;
testStr.Format("%s",ms);

return 0;
}

cuomj 2009-11-02
  • 打赏
  • 举报
回复
还有,你的需求很无聊啊
cuomj 2009-11-02
  • 打赏
  • 举报
回复
简单的办法,继承CString 并重载Format

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧