c++ - Windows API ReadFile() 跳过每两个字符中的一个
问题描述
我的目标是读取文件中的所有文本。出于某种原因,每当我从文件中读取并打印结果(drawText)时,缓冲区似乎每两个位置跳过一个字符。HELLO 将变为 HLO,而 SCAVENGER 将变为 SAEGR。
这适用于 Windows API。我想知道 CreateFile() 和 ReadFile() 是否很好,以及是否是其他原因导致了这个问题。
void init(HDC hdc)
{
HANDLE hFile;
LPCSTR fileName = "c:\\Users\\kanaa\\Desktop\\code\\HW2_StarterCode\\words.txt";
hFile = CreateFileA(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwFileSize = GetFileSize(hFile, NULL);
DWORD dwBytesRead;
WCHAR* buffer = new WCHAR[dwFileSize / 2 + 1];
buffer[dwFileSize / 2] = 0;
bool read = ReadFile(hFile, buffer, dwFileSize, &dwBytesRead, NULL);
std::wstring wstr(buffer);
std::string str(wstr.begin(), wstr.end());
delete[] buffer;
CloseHandle(hFile);
if (read) parse(str, hdc);
}
void parse(std::string word, HDC hdc)
{
std::string to = word;
std::wstring wword = std::wstring(to.begin(), to.end());
const WCHAR* wcword = wword.c_str();
Graphics graphics(hdc);
drawText(&graphics, wcword);
}
解决方案
您正在使用wchar_t[]
缓冲区处理文件数据。 wchar_t
在 Windows 上为 2 个字节。所以,在声明中:
std::string str(wstr.begin(), wstr.end());
您一次遍历文件数据 2 个字节,将每个字节对解释为一个wchar_t
被截断为 1-byte的单个字节char
,丢弃另一个字节。这就是为什么你str
最终会跳过所有其他角色。
改为使用char[]
缓冲区处理文件数据。但是,有更简单的方法可以将 7/8 位文件数据读入std::string
.
最后,在此声明中:
std::wstring wword = std::wstring(to.begin(), to.end());
这不是将 a 转换std::string
为 a的正确方法std::wstring
。您所做的只是遍历char
s 将每个原样转换为 2-byte wchar_t
。Windows API 期望wchar_t
字符串以 UTF-16 编码,而您的代码不会转换成这种格式。您需要使用MultiByteToWideChar()
,std::wstring_convert
或其他等效的 Unicode 库调用来执行该转换。在这种情况下,您首先需要知道源文件的编码才能正确地将其转换为 Unicode。
推荐阅读
- swift - 来自 swift 前端的 JSON 请求被解析为节点后端的额外字段
- python - 即使我有足够的行和列,带有输入()的矩阵也会显示“IndexError:列表索引超出范围”
- c# - 如何使用字典使 C# 中的代码整洁以用于统一脚本
- php - 如何为多个表单提交保留通过 URL 传递的变量?
- java - 初始化 List 和 ArrayList 有区别吗?
- sql - SQL 将字符串 hh:mm:ss 转换为十进制小时
- angular - Angular 10 后参数和正文
- llvm - 函数参数的 LLVM 过程间分析
- android - Android - React Native 集成 - TypeError:网络请求失败
- windows - PowerShell:如何检查本地帐户是否已启用/活动