vs2015 vc下有没有像linux那种 ##__VA_ARGS__可变参数宏呢?

baidu_28726667 2018-08-31 11:35:13
#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, ##__VA_ARGS__)

之前用linux封装了一个打印调试信息在用。但是最近换到windows发现没这个宏. 如果把 __FILE__, __LINE_ 封装到函数里面获取就只能一直显示函数里面的行数和对应文件名.. 网上有个__VA_ARGS__的方法需要用 _ 替换 , 也是反人类啊。。。有没有什么好方法呢?!
...全文
476 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eleven 2018-09-03
  • 打赏
  • 举报
回复
Windows里有这个宏:

#define MAX_BUF_SIZE (8192)
#define MAX_BIN_COUNT (16)
#define MAX_BIN_SIZE (64)

#define __STR2WSTR(str) L##str
#define _STR2WSTR(str) __STR2WSTR(str)

#ifdef UNICODE
#define _FILE_ _STR2WSTR(__FILE__)
#define _FUNCTION_ _STR2WSTR(__FUNCTION__)
#else
#define _FILE_ __FILE__
#define _FUNCTION_ __FUNCTION__
#endif

#define PARSE_ARGS(lpszFmt, szText, nLength) \
va_list args; \
va_start(args, lpszFmt); \
StringCchVPrintf(szText, nLength, lpszFmt, args); \
va_end(args);

#ifdef _DEBUG
#define DUMPPRINT(lpszFmt, ...) \
TCHAR szText[MAX_BUF_SIZE] = {0}; \
StringCchPrintf(szText, _COUNTOF_(szText), lpszFmt, __VA_ARGS__); \
OutputDebugString(szText);

#define DUMPFAILED(dwError) \
LPTSTR lpszBuf = NULL; \
TCHAR szError[MAX_BUF_SIZE] = {0}; \
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, LANG_NEUTRAL, (LPTSTR)&lpszBuf, 0, NULL); \
StringCchPrintf(szError, _COUNTOF_(szError), _T("\nError: File: %s \n\tLine: %d Function: %s()\n\tReason: %s\n"), _FILE_, __LINE__, _FUNCTION_, lpszBuf); \
OutputDebugString(szError); \
LocalFree(lpszBuf);

#define DUMPBIN(pData, dwSize) \
TCHAR szData[MAX_BIN_SIZE] = {0}; \
OutputDebugString(_T("\n-----------00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F")); \
for(DWORD i = 0; i < dwSize; i++) \
{ \
if(0 == (i % MAX_BIN_COUNT)) \
{ \
OutputDebugString(szData); \
StringCchPrintf(szData, _COUNTOF_(szData), _T("\n%08Xh: %02X"), i, pData[i]); \
} \
else \
{ \
StringCchPrintf(szData + _tcslen(szData), _COUNTOF_(szData) - _tcslen(szData), _T(" %02X"), pData[i]); \
} \
} \
OutputDebugString(szData); \
OutputDebugString(_T("\n----------------------------------------------------------\n"));
#else
#define DUMPPRINT(lpszFmt, ...)
#define DUMPFAILED(dwError)
#define DUMPBIN(pData, dwSize)
#endif
worldy 2018-09-03
  • 打赏
  • 举报
回复
char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;//这样的代码会有问题
}
函数退出后,逻辑上,其局部变量 str1[255] 已经不存在,除非你定义为static,返回其指针是错误的
baidu_28726667 2018-09-01
  • 打赏
  • 举报
回复
引用 4 楼 worldy 的回复:
[quote=引用 2 楼 baidu_28726667 的回复:]
使用__VA_ARGS__的时候发现,分隔也可以。编译也过了,输出似乎也没问题。 但是在宏定义上有个波浪线 “未找到用户定义的文本运算符” ?!

返回变量应该是有可能数据错了。。。

另外#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, __VA_ARGS__)
这个宏定义,传送进去的参数列表并不能直接转换成宽字符的样子,会出错 。。。

// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>

#define __GET_FL__ get_fl()
#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, __VA_ARGS__)

char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;
}

int main()
{
int a = 10;
char *b = "程序员";
double c = 5.44;

STD_LOG("测试程序[%d],[%s],[%lf]", a, b, c);

printf("%s\n", __GET_FL__);

system("pause");

return 0;
}


char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;//这样的代码会有问题
}[/quote]

引用 4 楼 worldy 的回复:
[quote=引用 2 楼 baidu_28726667 的回复:]
使用__VA_ARGS__的时候发现,分隔也可以。编译也过了,输出似乎也没问题。 但是在宏定义上有个波浪线 “未找到用户定义的文本运算符” ?!


// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>

#define __GET_FL__ get_fl()
#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, __VA_ARGS__)

char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;
}

int main()
{
int a = 10;
char *b = "程序员";
double c = 5.44;

STD_LOG("测试程序[%d],[%s],[%lf]", a, b, c);

printf("%s\n", __GET_FL__);

system("pause");

return 0;
}


char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;//这样的代码会有问题
}[/quote]

返回的是一个指针变量 ? 是有机会里面的值是乱的?!
zgl7903 2018-08-31
  • 打赏
  • 举报
回复
波浪线 是VS或VA的智能提示没有正确识别吧, 如果编译运行没有问题,可以不用理会
baidu_28726667 2018-08-31
  • 打赏
  • 举报
回复
使用__VA_ARGS__的时候发现,分隔也可以。编译也过了,输出似乎也没问题。 但是在宏定义上有个波浪线 “未找到用户定义的文本运算符” ?!


// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>

#define __GET_FL__ get_fl()
#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, __VA_ARGS__)

char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;
}

int main()
{
int a = 10;
char *b = "程序员";
double c = 5.44;

STD_LOG("测试程序[%d],[%s],[%lf]", a, b, c);

printf("%s\n", __GET_FL__);

system("pause");

return 0;
}
zgl7903 2018-08-31
  • 打赏
  • 举报
回复
worldy 2018-08-31
  • 打赏
  • 举报
回复
引用 2 楼 baidu_28726667 的回复:
使用__VA_ARGS__的时候发现,分隔也可以。编译也过了,输出似乎也没问题。 但是在宏定义上有个波浪线 “未找到用户定义的文本运算符” ?!


// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>

#define __GET_FL__ get_fl()
#define STD_LOG(args, ...) printf("文件名字[%s],程序行数[%d],日志内容["args"]\n", __FILE__, __LINE__, __VA_ARGS__)

char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;
}

int main()
{
int a = 10;
char *b = "程序员";
double c = 5.44;

STD_LOG("测试程序[%d],[%s],[%lf]", a, b, c);

printf("%s\n", __GET_FL__);

system("pause");

return 0;
}


char * get_fl()
{
char str1[255] = { 0 };
sprintf(str1,"%s %d %s",__FILE__, __LINE__, __FUNCTION__);
return str1;//这样的代码会有问题
}
​ 博主介绍:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌项目名称基于Web的酒店客房管理系统的设计与实现系统说明3.2.1  用户模块功能分析前台模块应主要包括用户登录模块、用户注册模块、查看客房信息模块、客房预定 模块、用户留言模块、充值模块和个人信息维护模块。用户登录模块:用户通过输入注册的的账号和密码,然后进行身份验证,匹配成功 后实现登录功能。用户注册模块:用户输入合法的账号和密码可以实现注册功能。 查看客房信息模块:用户可以通过首页查看客房的价格,图片,详情等信息,从而   可以选择想要预定的房间。 客房预定模块:用户选择自己想要预定的客房后,可以通过输入相关信息进行订房操作。用户留言模块:用户可以向管理员发送留言。 充值模块:用户可以通过添加银行卡再为自己进行充值操作。 个人信息维护模块:用户可以修改自己的姓名、密码、身份证号等信息,还可以查看自己的订单。3.2.2  管理员模块功能分析对于管理员而言,一个好的管理系统总是能让酒店的管理工作事半功倍[7]。管理员 能够通过这个系统对自己的酒店情况一目了然,应该包括客户留言模块、客房管理模 块、订房信息管理模块、入住信息管理模块、统计分析模块、酒店新闻管理模块、会 员信息管理模块、员工信息管理模块、系统用户管理模块、个人信息维护模块。客户留言模块:管理员可以查看并回复用户的留言。客房管理模块:管理员可以管理客房信息,可以添加新的客房,删除已经停用的客房信息,还可以修改现有的客房信息。订房信息管理模块:管理员可以处理用户的订房请求,为用户办理入住手续。入住信息管理模块:对于没有注册的线下客户,也可以办理入住手续。统计分析模块:可以对酒店所有的入住信息进行记录和总结分析。酒店新闻管理模块:管理员可以更新网站上的新闻公告,展示图片等信息。会员信息管理模块:管理员可以查看到所有的注册会员信息,可以对会员信息进行删除,修改,添加操作。员工信息管理模块:管理员可以查看到自己公司所有的员工信息,而且还可以对员工的相关信息进行管理。系统用户管理模块:管理员可以查看到所有的系统管理员信息并对管理员信息进行管理。个人信息维护模块:管理员可以更改自己的登录密码或者是姓名、性别、手机号等 相关个人信息。​编辑 环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 5.数据库:MySql 5.7版本;6.是否Maven项目:否;技术栈1. 后端:Spring+SpringMVC+Mybatis2. 前端:JSP+CSS+JavaScript+jQuery使用说明1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;3. 将项目中springmvc-servlet.xml配置文件中的数据库配置改为自己的配置;4. 运行项目,在浏览器中输入http://localhost:8080/ 登录运行截图​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑 用户管理控制层:package com.houserss.controller;import javax.servlet.http.HttpSession;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import com.houserss.common.Const;import com.houserss.common.Const.Role;import com.houserss.common.ServerResponse;import com.houserss.pojo.User;import com.houserss.service.IUserService;import com.houserss.service.impl.UserServiceImpl;import com.houserss.util.MD5Util;import com.houserss.util.TimeUtils;import com.houserss.vo.DeleteHouseVo;import com.houserss.vo.PageInfoVo;/** * Created by admin */@Controller@RequestMapping(/user/)public class UserController if (ip != null && ip.length() > 0) String[] ips = ip.split(,);for (int i = 0; i  

16,472

社区成员

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

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

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