c++ - 在将其存储到 char* 之前,控制台会在同一代码上显示问号

标签 c++ character

tnis 是一个长函数,但关键问题在 char* 变量中。 **在我将其转换为存储数据而不是打印到控制台之前,该功能运行良好。

我曾尝试使用 char[] 而不是 char* 那是我遇到缓冲区溢出错误的时候,所以现在它被分配时,它显示 ???整个控制台。 在 puts();

上连接和使用 char* 的正确方法是什么
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 2000\n");
                else if(osver.dwMajorVersion == 6) sprintf(s2,"Microsoft Windows Vista\n");
            }

            else if(osver.dwMinorVersion==1){
                if(osver.dwMajorVersion == 5) sprintf(s2,"Microsoft Windows XP\n");
                else if(osver.dwMajorVersion == 6) sprintf(s2,"Microsoft Windows 7\n");
            }
            else if(osver.dwMinorVersion==2){
                if(osver.dwMajorVersion == 5) sprintf(s2,"Microsoft Windows Server 2003 family\n");
            }
            else sprintf(s2,"unknown OS\n");
        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++ - 在将其存储到 char* 之前,控制台会在同一代码上显示问号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33307154/

相关文章:

python - 在python中将字符输出到终端中的某个位置

java - 如何使用 Java 检测和替换字符串中的不可打印字符?

C++如何访问从函数返回的对象的数据成员?

c++ - std::function 作为类的友元

java - 将字符串转换为字符数组

c - C 中的字符串分词器

class - 使用 Sed 和字符类从大写到小写

c++ - c++ 枚举的底层类型是什么?

c++ - 如何实现C++中使用的成员函数来转换C中的同一个程序?

c++ - POSIX (C++) 参数类型不匹配