0

これが私のコードです:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <tchar.h>

#define MAX_KEY_LENGTH 6

void CheckForUIMatch(TCHAR *ui, TCHAR *UIToFind, TCHAR *UIFound);

int _tmain(int argc, LPTSTR argv[])
{
    TCHAR UIToFind[24] = _T("hi***;en-US; ");
    TCHAR UIFound[24] = _T("");

    LPCTSTR placeToLook = _T("SYSTEM\\CurrentControlSet\\Control\\MUI\\UILanguages");

    HKEY UIKey;
    DWORD subkeyCounter = 0;
    TCHAR subkeyName[MAX_KEY_LENGTH];
    DWORD subkeyLength;
    DWORD subkeyAmount = 0;

    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, placeToLook , 0, KEY_READ, &UIKey) == ERROR_SUCCESS) {

            RegQueryInfoKey(UIKey, NULL, NULL, NULL, &subkeyAmount, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // Get the length of the longest subkey. 

            for (subkeyCounter = 0; subkeyCounter < subkeyAmount; subkeyCounter++) {
                subkeyLength = MAX_KEY_LENGTH;
                RegEnumKeyEx(UIKey,
                        subkeyCounter,
                        subkeyName,
                        &subkeyLength,
                        NULL,
                        NULL,
                        NULL,
                        NULL);
                CheckForUIMatch(subkeyName, UIToFind, UIFound);

            }
    } else {
        _tprintf(L"Faild to open the registry key!");
    }


    _tprintf(_T("Match: %s"), UIFound);

    return 0;
}

void CheckForUIMatch(TCHAR *ui, TCHAR *UIToFind, TCHAR *UIFound)
{
    int charToMatch;
    TCHAR* token = _tcstok(UIToFind, L";");
    while(token != NULL) {
        /* Check for exact match or general match */
        if ((token[_tcslen(token)-2] == '*') && (token[_tcslen(token)-1] == '*')) { // make general lang match
            charToMatch = 2;    
        } else {
            charToMatch = 5; // make exact lang match
        }

        _tprintf(L"\ntoken: %s, to match %d.\n", token, charToMatch); //Debug
        if(!_tcsncmp(token, ui, charToMatch)) {
            _tcsncat(UIFound, ui, charToMatch);
            _tcscat(UIFound, _T(";"));
        }
        token = _tcstok(NULL, L";");

    }
}

問題:

CheckForUIMatchのwhileループは1回だけ機能しているようですが、2回目にループが実行されると(たとえば、レジ​​ストリに複数のUIがある場合)、トークンの1つでのみループします。 (例:hi ***)2番目ではなく、ループを終了して2番目のトークンを取得する必要がある場合、デバッガーで2番目のトークンの代わりにBatPointerを取得することがわかります。

UIToFind TCHARをCheckForUIMatch関数内に直接配置すると、すべてが正常に機能しています。理由がわかりません。誰か知っていますか?

4

1 に答える 1

1

strtok検索文字列をインプレースで変更して、部分文字列を区切ります。あなたが呼ぶようにあなたの検索文字列はこうして進化しますstrtok

"hi***;en-US; "
"hi***\0en-US; "
"hi***\0en-US\0 "

の2回目の呼び出しでこの文字列を再利用しようとすると、最初の呼び出しで文字列が終了するため、strtok関数はそれを認識します。"hi***"'\0'

文字列を毎回分割する代わりに、一度分割するか、配列として宣言します。例:

LPCTSTR UiToFind[] = {_T("hi***"), _T("en-US") };
于 2012-07-03T09:43:08.867 に答える