2012-07-03 36 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") };