C strtok_在windbg中返回不正确的数据
(大家好)我对strtok_有些问题。我编写了这段代码(x64)C strtok_在windbg中返回不正确的数据,c,winapi,64-bit,windbg,strtok,C,Winapi,64 Bit,Windbg,Strtok,(大家好)我对strtok_有些问题。我编写了这段代码(x64) #包括 #包括 #包括 BOOL TestMD5(CONST WCHAR*MD5_数据库_文件) { HANDLE hFile=无效的\u HANDLE\u值; DWORD FileSize=0; DWORD dwReaded=0; PBYTE pData=NULL; 布尔面包=假; PCHAR令牌_字符串=NULL; PCHAR context=NULL; CONST PCHAR delimeter=“\r\n”; hFile=
#包括
#包括
#包括
BOOL TestMD5(CONST WCHAR*MD5_数据库_文件)
{
HANDLE hFile=无效的\u HANDLE\u值;
DWORD FileSize=0;
DWORD dwReaded=0;
PBYTE pData=NULL;
布尔面包=假;
PCHAR令牌_字符串=NULL;
PCHAR context=NULL;
CONST PCHAR delimeter=“\r\n”;
hFile=CreateFileW(
MD5_数据库_文件,
泛读,
文件共享读取,
无效的
开放式,
文件\u属性\u正常,
无效的
);
if(hFile==无效的句柄值)
{
wprintf(L“无法打开md5数据库文件:”);
返回FALSE;
}
FileSize=GetFileSize(hFile,NULL);
if(FileSize==0 | | FileSize==INVALID_FILE_SIZE)
{
闭合手柄(hFile);
返回FALSE;
}
pData=(PBYTE)HeapAlloc(GetProcessHeap(),HEAP\u ZERO\u内存,(SIZE\u T)FileSize);
if(pData==NULL)
{
闭合手柄(hFile);
返回FALSE;
}
bRead=ReadFile(hFile、pData、FileSize和dwReaded,NULL);
if(bRead!=TRUE | | dwReaded!=FileSize)
{
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回FALSE;
}
令牌字符串=(PCHAR)strtok字符串(pData、delimeter和context);
if(令牌_字符串==NULL)
{
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回FALSE;
}
做{
printf(“%s\n”,标记\u字符串);
}while(token_string=(PCHAR)strtok_s(NULL、delimeter和context));
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回TRUE;
}
内部主(空)
{
WCHAR*MD5_DATABASE_FILE=L“c:\\MD5.txt”;
TestMD5(MD5_数据库_文件);
}
当我运行exe时,这会给我错误的数据。md5.txt的内容(DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG+(\r\n)
输出:
D:\repos\TestWindbg\x64\Debug>TestWindbg.exe
DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG
轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧轧
我在windbg中打开exe,我看到while(token_string)在第一次之后不是空的。但它必须是空的吗
WinDbg图像:“
有什么问题吗?感谢阅读我只是更改了一些类型的
pData
和token\u string
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD FileSize = 0;
DWORD dwReaded = 0;
char* pData = NULL;
BOOL bRead = FALSE;
char* token_string = NULL;
PCHAR context = NULL;
CONST PCHAR delimeter = "\r\n";
hFile = CreateFileW(
MD5_DATABASE_FILE,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
wprintf(L"Can't open md5 database file: ");
return FALSE;
}
FileSize = GetFileSize(hFile, NULL);
if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
{
CloseHandle(hFile);
return FALSE;
}
pData = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1);
if (pData == NULL)
{
CloseHandle(hFile);
return FALSE;
}
bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
if (bRead != TRUE || dwReaded != FileSize)
{
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return FALSE;
}
token_string = strtok_s(pData, delimeter, &context);
if (token_string == NULL)
{
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return FALSE;
}
do {
printf("%s\n", token_string);
} while (token_string = strtok_s(NULL, delimeter, &context));
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return TRUE;
}
int main(void)
{
WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";
TestMD5(MD5_DATABASE_FILE);
}
#包括
#包括
#包括
BOOL TestMD5(CONST WCHAR*MD5_数据库_文件)
{
HANDLE hFile=无效的\u HANDLE\u值;
DWORD FileSize=0;
DWORD dwReaded=0;
char*pData=NULL;
布尔面包=假;
char*token_string=NULL;
PCHAR context=NULL;
CONST PCHAR delimeter=“\r\n”;
hFile=CreateFileW(
MD5_数据库_文件,
泛读,
文件共享读取,
无效的
开放式,
文件\u属性\u正常,
无效的
);
if(hFile==无效的句柄值)
{
wprintf(L“无法打开md5数据库文件:”);
返回FALSE;
}
FileSize=GetFileSize(hFile,NULL);
if(FileSize==0 | | FileSize==INVALID_FILE_SIZE)
{
闭合手柄(hFile);
返回FALSE;
}
pData=(char*)HeapAlloc(GetProcessHeap(),HEAP\u ZERO\u内存,(SIZE\u T)FileSize+1);
if(pData==NULL)
{
闭合手柄(hFile);
返回FALSE;
}
bRead=ReadFile(hFile、pData、FileSize和dwReaded,NULL);
if(bRead!=TRUE | | dwReaded!=FileSize)
{
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回FALSE;
}
令牌字符串=strtok字符串(pData、delimeter和上下文);
if(令牌_字符串==NULL)
{
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回FALSE;
}
做{
printf(“%s\n”,标记\u字符串);
}while(token_string=strtok_s(NULL、delimeter和context));
HeapFree(GetProcessHeap(),0,pData);
闭合手柄(hFile);
返回TRUE;
}
内部主(空)
{
WCHAR*MD5_DATABASE_FILE=L“c:\\MD5.txt”;
TestMD5(MD5_数据库_文件);
}
输出:
DC288E0B39EA16B4E9455F82FF265A67:1213:TestDBG+(\r\n)Jeffrey Shao-MSFT:谢谢你的回复,但这不是解决方案(但我将代码PBYTE更改为PCHAR)。问题是strtok_是一个字符串函数,因此必须在buff之后添加空字节。如
HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize+1)
#1表示空字符。HeapAlloc alloc buff大小:FileSize和+1表示空字符
感谢blabb和Daniel Sęk:不要使用strtok_S,它不像你想象的那样工作。定义
\u CRT_SECURE\u NO_WARNINGS
并改用strtok
。谢谢你的回复。但是微软说strtok_S比strtok更安全?你发布的代码不是多线程的,因此,自然不会调用strtokk()
在多个线程中,因此不会出现问题User3629249:谢谢回复。我知道,但我的问题不同此代码打印不正确的数据以输出。你确定你发布的代码和正在调试的代码相同吗?我没有看到屏幕截图中的do while循环也避免条件表达式中的赋值不要使用c:\it Is在winx中通常不可写。不要将pbyte强制转换为pchar。memdump在+后面有一个空字符,并且只有0x0a不是0x0d 0x0a可能是strok。在其他地方找到了\r\n是否检查了偏移量?
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD FileSize = 0;
DWORD dwReaded = 0;
char* pData = NULL;
BOOL bRead = FALSE;
char* token_string = NULL;
PCHAR context = NULL;
CONST PCHAR delimeter = "\r\n";
hFile = CreateFileW(
MD5_DATABASE_FILE,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
wprintf(L"Can't open md5 database file: ");
return FALSE;
}
FileSize = GetFileSize(hFile, NULL);
if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
{
CloseHandle(hFile);
return FALSE;
}
pData = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1);
if (pData == NULL)
{
CloseHandle(hFile);
return FALSE;
}
bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
if (bRead != TRUE || dwReaded != FileSize)
{
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return FALSE;
}
token_string = strtok_s(pData, delimeter, &context);
if (token_string == NULL)
{
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return FALSE;
}
do {
printf("%s\n", token_string);
} while (token_string = strtok_s(NULL, delimeter, &context));
HeapFree(GetProcessHeap(), 0, pData);
CloseHandle(hFile);
return TRUE;
}
int main(void)
{
WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";
TestMD5(MD5_DATABASE_FILE);
}