"错误'SetWindowTextA':不是'CStatic'的成员,char *fgets(char*, int, FILE*):无法将参数1从'TCHAR'转换为'char*'



我将C++项目从Visual Studio 2005迁移到Visual Studio 2017 Professional,当我在调试和发布模式下构建时,我会收到以下错误:

1.

在调试构建中,当我使用SetWindowTextA时,如下所示,我会收到错误"错误C2039‘SetWindowTextA':不是‘CStatic’的成员

m_status_text.SetWindowTextA(theStr);

m_status_text被声明为CStatic,如下所示:

CStatic m_status_text;

如果我使用SetWindowTextW,它会在Release Build中引发一个错误。

m_status_text.SetWindowTextW(theStr);

当我将其更改为"SetWindowText"时,如下所示,它同时适用于Debug和Release Build。这是正确的方式吗?

m_status_text.SetWindowText(theStr);

据我所知,当我们使用"SetWindowText"时,在Unicode格式中,它将其视为"SetWindowTextW",而对于多字节字符集格式,它将视为"SetWindowTextA"。

但是SetWindowText是如何用于调试和发布版本的呢?

2.

此外,我们可以像在调试构建中那样使用"_fgetts"而不是"fgets"(对于发布构建("fgetws"(对于调试构建(吗?如果我使用"fgts",我会得到以下错误:

charfgets(char,int,FILE*(:无法将参数1从"TCHAR[260]"转换为"char*">

fgets(currDir,MAX_PATH,f);    // For release build
fgetws(currDir, MAX_PATH, f); // For Debug build
  1. 我可以使用"_tfopen"代替"fopen(用于发布版本("one_answers"_wfopen"(用于调试版本(吗

    f=_ fopen(文件名,_T("r"((;

代替

f = fopen(fileName,"r");  // For release build
f = _wfopen(fileName, L"r"); // For Debug build

请帮我一下。

Windows API为每个处理或允许字符串作为参数的函数提供了两种变体:

  • UNICODE,通常函数名将以W结尾
  • ANSI:函数名称将以A结尾

然后,Windows API为所有这些函数提供了一个通用变体,没有尾随的a或W字母,该变体将映射到上面的一个(a或W(,具体取决于是否定义了UNICODE。

示例:

SetWindowText

映射到:
-SetWindowTextA(如果未定义UNICODE(=>ANSI((
-SetWindowTextW(如果UNICODE定义为(

UNICODE变体将字符串处理为wchar_t*,而ANSI变体将字符串处理为char*。

TCHAR是宏定义的字符类型,它映射到char或wchar_t,具体取决于是否定义UNICODE:
-TCHAR=char如果未定义UNICODE
-TCHAR=wchar_t

对于"现代"Windows应用程序,VS2017默认使用UNICODE模式(这是VC++项目文件的一个选项(,我建议您继续使用,除非您绝对必须支持Windows的旧版本(即98(
使用UNICODE模式,您将使用SetWindowTextW((函数变体(或仅使用SetWindowText(((,并向其传递wchar_t*(或TCHAR*(字符串。

如果您需要在ANSI和UNICODE模式下支持或编译项目,可能需要使用TCHAR类型,但现在很少需要它。

在您的问题中,您似乎混合了两个相互正交的轴:ANSI与Unicode构建,以及Debug与Release构建。

RE#1 ANSI与Unicode函数调用,当您调用MFC类方法时,您应该简单地调用"未修饰">方法名称,例如:

// Note the use of the "undecorated" SetWindowText method call:
m_status_text.SetWindowText(theStr);
// This gave you an error:
// m_status_text.SetWindowTextA(theStr);

这与调试版本和发布版本无关,后者会影响运行时性能等其他方面。事实上,通常在调试构建中,会有更多的代码被编译并检查不变量和其他安全方面,比如确保索引不会跨越安全的数组边界,或者STL容器中迭代器的正确使用,等等。
所有这些额外的调试构建检查往往会产生效率较低的代码,但这些相同的调试检查可以帮助您检测各种错误,在发布更高效的应用程序版本之前,您可以修复这些问题。

但是,同样,这独立于ANSI与Unicode构建模式方面。


RE#2在发布版本和调试版本中使用不同的文件函数:如果真的需要(你确定吗?你实际上想实现什么?(,你可以使用这样的#ifdef

#ifdef _DEBUG
// Debug-build specific code
// ...
#else 
// Release-build specific code
// ...
#endif

当然,您可以在Debug和Release版本中使用fopen_wfopen_tfopen:同样,这些Unicode/MBCS和Debug/Release版本是正交的。

p。S.一般来说,我鼓励您将代码库转移到Unicode,只在Unicode模式下构建(调试Unicode和发布Unicode(。

最新更新