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 循环似乎只工作一次,但在第二次运行循环时(例如,当在注册表中找到多个 UI 时),它仅在其中一个令牌上循环(例如嗨***)而不是在第二个,一旦它结束循环并需要获取第二个令牌,我可以在调试器中看到它得到 BatPointer 而不是第二个令牌。

如果我将 UIToFind TCHAR 直接放在 CheckForUIMatch 函数中,一切正常,我不知道为什么?有人知道吗?

4

1 回答 1

1

strtok就地修改搜索字符串以分隔子字符串。您的搜索字符串会随着您的调用而演变strtok

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

当您尝试在对 的第二轮调用中重用此字符串时strtok,该函数会看到,"hi***"因为第一次调用'\0'终止了该字符串。

不要每次都拆分字符串,而是拆分一次或将其声明为数组,例如:

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