未定义标识符“L“,sprintfw/swprintf用法,TEXT宏

"在使用Windows API的CreateWindow函数时,遇到VS报错问题。通过控制变量法排查,发现错误在于将文本参数错误理解。了解到LPCTSTR类型与TEXT宏的用途,以及需要将char类型转换为宽字符。最终使用swprintf函数和"%S"格式化字符串解决了问题,使代码不再报错。"
摘要由CSDN通过智能技术生成

起因

在这里插入图片描述

用Windows api写程序的时候,使用CreateWindow函数,用vs跑会报错,如上。
通过控制变量来排查错误,明白两点:

  1. 控制变量应该先从每个参数开始怀疑
  2. 未定义标识符其实说的是文本未定义【当第二个变量进行变化的时候,这个标识符会变化】

我的代码:

check_box[i] = CreateWindow(
	TEXT("button"), TEXT(&check_text[i]),
	WS_CHILD | WS_VISIBLE | BS_LEFT | BS_AUTOCHECKBOX/*复选框*/,
	x, y, 50, 26,
	hWnd, (HMENU)id_tmp, hInst, NULL
);

经过

微软中的定义:

void CreateWindowW(
   lpClassName,
   lpWindowName,
   dwStyle,
   x,
   y,
   nWidth,
   nHeight,
   hWndParent,
   hMenu,
   hInstance,
   lpParam
);

第二个参数,我开始把text当成了一个函数,然后只顾着传递参数了,现在踩了坑才知道这是个宏。

关于该宏

这个宏的作用是:标识一个字符串为宽字符字符串,Unicode

为什么要用这个宏呢?显然是要匹配第二个参数类型,第二个参数是LPCTSTR类型的,也就是CONST TCHAR *类型,关于微软的数据类型可以看它的官方文件

而我定义的变量是char类型的数组,我当然要转换一下,转换方法是使用swprintf函数【1】

与该函数类似的函数sprintf的使用方法有如下例子:

   j  = sprintf( buffer,    "   String:    %s\n", s ); // C4996
   j = sprintf( buffer, "   Character: %c\n", c ); // C4996
   j = sprintf( buffer, "   Integer:   %d\n", i ); // C4996
   j = sprintf( buffer, "   Real:      %f\n", fp );// C4996

官网是这样说的

但是我的vs好像又不支持:
在这里插入图片描述
递归查询各种资料绕了一大圈(包括去找什么string到wchar_t的转换啦,去官网反复看sprintf、_sprintf_l、swprintf, _swprintf_l、__swprintf_l这些的定义啦等等,qswl)后才知道,在swprintf中要写成这样:"%S"【大写】,才可以转换字符串。而这一点,在本文中带有上标【1】的博客里已经写出来了。我反复去世。使我找到错误的是官方的另一个链接。这个链接详细阐述了printf和wprintf函数的输出格式问题,syntax……

结果

修改代码为:

TCHAR buffer[12];
swprintf(buffer, L"%S", check_text[i]);
check_box[i] = CreateWindow(
	TEXT("button"), buffer[i],
	WS_CHILD | WS_VISIBLE | BS_LEFT | BS_AUTOCHECKBOX/*复选框*/,
	x, y, 50, 26,
	hWnd, (HMENU)id_tmp, hInst, NULL
);

然后vs终于不报错了。我都不敢运行了,祝我好运……

收获

附上一个Windows api手册微软中文官网

  1. 对syntax转换有了一定了解,深深记住了只要我想到的,别人就一定已经做过了,开发程序的人员一定做得比我需要得更普适
  2. 发现了微软的官网这个好东西,这个手册真棒!有很多开发相关的知识,但是用好它的前提是熟练它的结构和搜索引擎

后记

后来,我发现我的程序还是无法运行:
在这里插入图片描述
然后我想到了从定义的位置开始就用Unicode:

  1. 改前:
    在这里插入图片描述
  2. 改后:
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值