2012-07-03 34 views
0

這裏是我的代碼:_tcstok(strtok)在令牌上跳轉嗎?

#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),它只在其中一個令牌(例如hi ***)上循環,而不在第二個循環中,一旦它結束循環並需要獲得我可以看到的第二個令牌調試器,它獲得BatPointer而不是第二個令牌。

如果我把UIToFind TCHAR直接放在CheckForUIMatch函數中,一切工作正常,我不知道爲什麼?有人知道嗎?

+2

你有更好的機會得到答案,如果你更換所有註冊表的東西在你的主有兩個電話,傳遞兩個硬編碼的字符串,這再現了問題。更好的是,嘗試發佈再現問題的最少量代碼,而不需要任何額外的邏輯。也可以幫助您專注於問題的原因,因爲當您刪除起初似乎不相關的代碼時,它可能會消失。 – eran

回答

1

strtok修改搜索字符串以便分隔子字符串。您撥打strtok搜索字符串從而演變:

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

當您嘗試在第二輪的呼叫到strtok重用這個字符串,函數看到"hi***"因爲第一'\0'終止字符串。

不是每次都分割字符串,分割一次或聲明它作爲一個數組,如:

LPCTSTR UiToFind[] = {_T("hi***"), _T("en-US") };