这是一个很长的函数,但关键问题是在char*变量。**在我将其转换为存储数据而不是打印到控制台之前,该函数工作正常。
我试图使用char[]
而不是char*
,那是当我得到一些缓冲区溢出错误时,所以现在它被分配,它显示??控制台到处都是。char*
在puts();
上的正确连接和使用方法是什么
MySystemInfo Msi;
puts(Msi.getOsInfo());
char* MySystemInfo::getOsInfo()
{
OSVERSIONINFOEX osver;
BOOL bOsVersionInfoEx;
HKEY hKey;
LONG lRet;
char* RtTmpOsInfo= (char *) malloc(sizeof(char)*70);
char* s1=(char *) malloc(sizeof(char)*20);
char* s2=(char *) malloc(sizeof(char)*50);
// Try calling GetVersionEx() using the OSVERSIONINFOEX structure.
// If that fails, try using the OSVERSIONINFO structure.
ZeroMemory(&osver, sizeof(OSVERSIONINFOEX));
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osver)))
{
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx((OSVERSIONINFO *) &osver))
return "";
}
switch (osver.dwPlatformId)
{
//Test for the Windows NT product family.
case VER_PLATFORM_WIN32_NT:
if(osver.dwMajorVersion <4> BUFSIZE) return "";
sprintf( s1,"v%d.%d "+ osver.dwMajorVersion, osver.dwMinorVersion);
// Test for the specific product family.
if(osver.dwMinorVersion==0){
if(osver.dwMajorVersion == 5) sprintf(s2,"Microsoft Windows 2000n");
else if(osver.dwMajorVersion == 6) sprintf(s2,"Microsoft Windows Vistan");
}
else if(osver.dwMinorVersion==1){
if(osver.dwMajorVersion == 5) sprintf(s2,"Microsoft Windows XPn");
else if(osver.dwMajorVersion == 6) sprintf(s2,"Microsoft Windows 7n");
}
else if(osver.dwMinorVersion==2){
if(osver.dwMajorVersion == 5) sprintf(s2,"Microsoft Windows Server 2003 familyn");
}
else sprintf(s2,"unknown OSn");
break;
}
strcat(RtTmpOsInfo,s1);
strcat(RtTmpOsInfo,s2);
//lRet/* = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Hotfix\Q246009", 0, KEY_QUERY_VALUE, &hKey);
// printf("Service Pack 1 (Build %d)n", osver.dwBuildNumber & 0xFFFF);*/
return RtTmpOsInfo;
}
std::strcat
在目标缓冲区中查找空字节。然而,RtTmpOsInfo
所指向的缓冲区是未初始化的,所以在它上面调用std::strcat
会导致未定义的行为。
代替第一个std::strcat
调用,只使用
strcpy(RtTmpOsInfo,s1);
或者,如果你不确定s1
是否真的有一个空字节,
strncpy(RtTmpOsInfo, s1, SOME_CONSTANT);
SOME_CONSTANT
为写入RtTmpOsInfo
的最大字节数。由于您将此问题标记为[c++]
而不是[c]
,我建议您放弃使用难以读取/使用/维护的原始C类字符串缓冲区(以及相关的不安全字符串函数,如strcat
),而是使用方便的c++字符串类。
例如,您可以使用std::string
,您可以返回std::string
实例而不是原始的char*
(与char*
原始指针的生命周期相关的所有问题!)。
您可以使用std::string
的重载 operator+
和 +=
以非常直观自然的方式连接子字符串。
或者您可以使用 std::ostringstream
类,使用operator<<
的流语义构建整个字符串。
在这种情况下,一旦你的整个字符串组成,你可以只调用 ostringstream::str()
方法来获得一个std::string
实例返回给调用者。
这样,你的代码会更简单,更清晰,更少bug。