未定义标识符“L“,sprintfwswprintf用法,TEXT宏

it2026-03-30  6

文章目录

起因经过结果收获后记

起因

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

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

我的代码:

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手册和微软中文官网

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

后记

后来,我发现我的程序还是无法运行: 然后我想到了从定义的位置开始就用Unicode:

改前: 改后:
最新回复(0)