2

重複の可能性:
文字列を比較する方法


レジストリ文字列値と比較したいのですが、それらが同じ場合はメッセージボックスが表示されます
現在、この関数を使用しています , 値を正しく返しますが、それらを比較したいときはいつでも, 比較結果は常に間違っています

char* GetRegistry(char* StringName)
{
DWORD dwType = REG_SZ;
HKEY hKey = 0;
char value[1024];
DWORD value_length = 1024;
const char* subkey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\MCI\\Player";
RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&hKey);
RegQueryValueEx(hKey, StringName, NULL, &dwType, (LPBYTE)&value, &value_length);
return  value;
}


私はそれらを比較するためにこれを使用します

if (GetRegistry("First") == GetRegistry("Second"))
{
MessageBox(NULL,":|",":|",1);
}


しかし、MessageBoxはどのように表示されますか値は異なります


どんな助けでも大歓迎です。

4

3 に答える 3

5

を使用するstd::stringと、比較は期待どおりに動作します。また、関数がローカル バッファーへのポインターを返すという別のバグも修正されます。

std::string GetRegistry(const char* StringName)
{
....
return std::string(value);
}
于 2012-10-18T12:51:01.723 に答える
4

GetRegistry()を返すので、実際にはポインタを とchar*比較しています。を使用して生の C のような文字列比較を行うか、またはのような堅牢な C++ 文字列クラスを使用することをお勧めします。operator==strcmp()char*CStringstd::[w]string

以下は、ATL を使用した関数の書き直しの可能性ですCString

#include <atlbase.h>
#include <atlstr.h>

CString GetRegistry(LPCTSTR pszValueName)
{
    // Try open registry key
    HKEY hKey = NULL;
    LPCTSTR pszSubkey = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\MCI Extensions");
    if ( RegOpenKey(HKEY_LOCAL_MACHINE, pszSubkey, &hKey) != ERROR_SUCCESS )
    {
        // Error:
        // throw an exception or something...
        //
        // (In production code a custom C++ exception 
        // derived from std::runtime_error could be used)
        AtlThrowLastWin32();
    }

    // Buffer to store string read from registry
    TCHAR szValue[1024];
    DWORD cbValueLength = sizeof(szValue);

    // Query string value
    if ( RegQueryValueEx(
            hKey,
            pszValueName, 
            NULL, 
            NULL, 
            reinterpret_cast<LPBYTE>(&szValue), 
            &cbValueLength) 
         != ERROR_SUCCESS )
    {
        // Error
        // throw an exception or something...
        AtlThrowLastWin32();
    }

    // Create a CString from the value buffer
    return CString(szValue);
}

そして、次のように呼び出すことができます。

if ( GetRegistry(_T("First")) == GetRegistry(_T("Second")) )
    ...

このコードは、ANSI/MBCS ビルドと Unicode ビルドの両方でコンパイルされることに注意してください (Win32TCHARモデルに基づいています)。

于 2012-10-18T12:48:12.740 に答える
0

このソース コードにはいくつかの問題があります。

まず第一に、スタック上の変数であるローカル変数を持つ関数があり、その変数のアドレスを返しますが、関数が戻ると、変数は消え、アドレスは無効になります。

次の問題は、文字列を比較していないことです。代わりに、関数によって返されたアドレスを比較しています。運が良ければ、アドレスは同じである可能性があります。関数を 2 回続けて呼び出しているため、幸運にもアドレスが同じになります。

次のことをお勧めします: (1) 関数を呼び出している関数内に 2 つのローカル文字列を作成しGetRegistry()、(2) 関数を変更してGetRegistry()、独自のバッファーではなくそれらのバッファーを使用するようにします。したがって、コードは次のようになります。

char registryEntryOne[1024];
char registryEntryTwo[1024];
DWORD dwRegistryEntryOneLen;
DWORD dwRegistryEntryTwoLen;

registryEntryOne[0] = 0;   // init the registry entry to zero length string
registryEntryTwo[0] = 0;

dwRegistryEntryOneLen = sizeof(registryEntryOne);
GetRegistry ("First", registryEntryOne, &dwRegistryEntryOneLen);
dwRegistryEntryTwoLen = sizeof(registryEntryTwo);
GetRegistry ("Second", registryEntryTwo, &dwRegistryEntryTwoLen);

// two strings are equal if:
//   the lengths are the same
//   at least one of the lengths is non-zero
//   the bytes are the same in the same order
if (dwRegistryEntryOneLen && dwRegistryEntryOneLen == dwRegistryEntryTwoLen && memcmp (registryEntryOne, registryEntryTwo, dwRegistryEntryOneLen) == 0) {
    // strings are equal
} else {
    // strings are not equal
}

GetRegistry() 関数は次のようになります。

char* GetRegistry(char* StringName, char *valueBuffer, DWORD *value_length)
{
    DWORD dwType = REG_SZ;
    HKEY hKey = 0;
    const char* subkey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\MCI\\Player";

    RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&hKey);
    RegQueryValueEx(hKey, StringName, NULL, &dwType, (LPBYTE)valueBuffer, value_length);
    return  valueBuffer;
}
于 2012-10-18T13:04:34.207 に答える