写入 C:Program Files 中包含的文件夹的文件名
Write into a file names of folders containing in C:Program Files
我有这个任务:
1. 在当前目录中创建文件 subMape.dat
2.将存储在C:\Program Files folder
中的所有文件夹名称写入其中3.在屏幕上显示数据,这是用子Mape编写的.dat
#include <iostream>
#include <windows.h>
using namespace std;
int main() {
WIN32_FIND_DATA findFileData;
DWORD bytesWritten = 0;
HANDLE f;
HANDLE c = CreateFileW(L"subMape.txt", GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//TCHAR lpBuffer[32];
DWORD nNumberOfBytesToRead = 32;
//DWORD lpNumberOfBytesRead;
DWORD lengthSum = 0;
if (c) {
cout << "CreateFile() succeeded!n";
if(f = FindFirstFile(L"C:\Program Files\*", &findFileData)){
if(f != INVALID_HANDLE_VALUE) {
while (FindNextFile(f, &findFileData)){
lengthSum += bytesWritten;
WriteFile(c, findFileData.cFileName, (DWORD)wcslen(findFileData.cFileName), &bytesWritten, NULL);
}
}
FindClose(f);
}
else {
cout << "FindFirstFile() failed :(n";
}
}
else {
cout << "CreateFile() failed :(n";
}
cout << lengthSum << endl;
//SetFilePointer(c, lengthSum, NULL, FILE_BEGIN);
//ReadFile(c, lpBuffer, lengthSum, &lpNumberOfBytesRead, NULL);
//wprintf(lpBuffer);
CloseHandle(c);
return 0;
}
我正在使用UNICODE,当它写入findFileData.cFileName时 - 它写入字符串,其中字符用空格分割。例如:文件夹名称"新建文件夹"(strlen = 10)将作为"N e w T o"(strlen = 10)写入文件。怎么办?
您的文本文件查看器或编辑器不够智能,无法确定您编写了 utf-16 编码的文本文件。 大多数文本编辑器需要帮助,将 BOM 写入文件:
cout << "CreateFile() succeeded!n";
wchar_t bom = L'xfeff';
WriteFile(c, &bom, sizeof(bom), &bytesWritten, NULL);
您需要使用 WideCharToMultiByte()
之类的东西将 UNICODE 字符串转换为 ANSI(或 UTF8)。
您看到"空格"的原因是您用于列出文件的程序将其视为每个字符一个字节。在窗口中使用 Unicode 时,你会得到两个,第二个字节是"\0"。
您需要选择对文件中的数据进行编码的方式。
最简单的方法是使用 UTF-16LE
,因为这是 Windows 上的本机编码。然后,您只需要在文件的开头附加一个字节顺序标记。这种编码比UTF-8
具有优势,因为由于观察到的零字节,它很容易从extended ASCII
编码中推断出来。它的缺点是您需要BOM
并且占用更多未压缩的磁盘空间。
UTF-8
的优点是更紧凑。它也与纯ASCII
完全兼容,并受到编程社区的青睐。
如果您不需要在任何上下文中使用extended ASCII
,则应在 UTF-8
中对数据进行编码。如果这样做,请使用 UTF-16LE
。
那些认为通过UTF-8
验证的文本是用UTF-8
编码的人,如果整个文本都可用,这是正确的,但如果不是,则错误:
考虑按字母顺序排列的瑞典名字列表。如果我只检查列表的第一部分并且它是Latin-1
(ISO/IEC 8859-1
),它也将通过UTF-8
测试。
最后是"Örjansson",它分解成mojibake,事实上,"Ö"将是一个无效的UTF-8
位序列。另一方面,由于使用UTF-16LE
时使用的所有字母实际上都适合一个字节,我可以完全确信它不是UTF-8
,也不是Latin-1
。
你应该知道,在Windows中,"本机"uncidode格式是UTF-16,由W样式函数(CreateFileW)使用。考虑到这一点,编写文件应该会给你一个有效的 UTF-16 文本,但编辑器可能没有认识到这一点,为了确保你的程序正常工作,请使用文本编辑器,您可以在其中手动指定编码(你知道它需要什么)以防它无法识别它,因为这个记事本++是一个不错的选择。
正如其他人已经提到的,编写 BOM 对文本编辑器非常有帮助,并确保您的文件将被正确读取。
您可以使用 WideCharToMultiByte 将 UTF-16 转换为 UTF-8,以获得更高的兼容性。
为什么你直接使用CreateFileW而不是FindFirstFileW,在你的项目中定义了UNICODE?如果你这样做,编译器会为你解析CreateFile到CreateFileW。
另外,这里
WriteFile(c, findFileData.cFileName, (DWORD)wcslen(findFileData.cFileName), &bytesWritten, NULL);
wcslen给出的字符数与非ANSI文本的数据大小不同,它应该是这样的
wcslen(findFileData.cFileName)*sizeof(wchar_t)
在处理 UTF-16 文件时,写入字节顺序标记并写入长度以字节而不是字符为单位的数据非常重要。 wcslen
返回以字符为单位的字符串长度,但在使用宽字符串时,字符为两个字节。 这是一个固定版本。 它显式调用 Win32 API 的宽版本,因此无论是否定义 UNICODE/_UNICODE都将起作用。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
WIN32_FIND_DATAW findFileData; // Use the wide version explicitly
DWORD bytesWritten = 0;
HANDLE f;
HANDLE c = CreateFileW(L"subMape.txt", GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD lengthSum = 0;
if(c != INVALID_HANDLE_VALUE) {
cout << "CreateFile() succeeded!n";
// Write A byte-order mark...make sure length is bytes not characters.
WriteFile(c, L"uFEFF", sizeof(wchar_t), &bytesWritten, NULL);
lengthSum += bytesWritten;
f = FindFirstFileW(L"C:\Program Files\*", &findFileData);
if(f != INVALID_HANDLE_VALUE) {
while(FindNextFileW(f, &findFileData)) {
// Write filename...length in bytes
WriteFile(c, findFileData.cFileName, (DWORD)wcslen(findFileData.cFileName) * sizeof(wchar_t), &bytesWritten, NULL);
// Add the length *after* writing...
lengthSum += bytesWritten;
// Add a carriage return/line feed to make Notepad happy.
WriteFile(c, L"rn", sizeof(wchar_t) * 2, &bytesWritten, NULL);
lengthSum += bytesWritten;
}
FindClose(f); // This should be inside findFirstFile succeeded block.
}
else {
cout << "FindFirstFile() failed :(n";
}
// these should be inside CreateFile succeeded block.
CloseHandle(c);
cout << lengthSum << endl;
}
else {
cout << "CreateFile() failed :(n";
}
return 0;
}
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- vcruntime.h 从 Windows 包含文件夹中丢失?
- 当包含头文件的文件不在根项目文件夹中时,如何包含它
- 使用g++包含来自不同文件夹的头文件
- 使用文件对话框选择包含特定文件类型的文件夹?
- 如何将包含C++文件的文件夹添加到 NetBeans 项目中
- 我可以在C 中的Windows中读取一个文件,而无需锁定包含文件的文件夹
- 如何在 exe 文件夹中不包含纹理
- 无法创建将包含日志文件的文件夹
- Qt C++:将所有库文件包含在项目文件夹中
- 如何将包含多个.cpp源文件的文件夹导入Eclipse项目中,每个源文件都有一个main()定义
- 在 CMAKE 中包含来自 Android 项目不同文件夹的静态库
- C++项目文件夹外部依赖项仅包含 .h 和 .hpp 文件
- 嵌入 LuaJIT - 创建包含文件夹
- Coapp / autopkg :/build/native/include/ 中的多个包含文件夹
- 编译C++程序,如何正确链接到包含文件夹
- VS2013 C++:忽略平台包含文件夹
- 在 Visual Studio 项目中创建包含文件夹和 Lib 文件夹
- 如何包含文件夹中的所有源文件?(C++,MS与2013年相比)
- 有没有关于如何将包含文件夹和文件的zip文件解压缩到某个目录并通过MiniZip将其打包的教程