- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用以下代码读取我在文本编辑器 (Notepad++) 中创建的文本 (.xml) 文件,将我从中读取的 UTF-8 文本转换为 UTF-16,以便 Windows API 函数可以使用它,然后将这个 UTF-16 编码的文本写回第二个文件。
我的问题是,当我在 Notepad++ 中打开输出文件时,无论我要求文本编辑器使用哪种编码,我都没有得到我期望看到的内容。文件中几乎每个字符之前都有空字符。我假设我在将 UTF-16 写入输出文件时做错了什么,或者 Notepad++ 正在读取单字节字符。
有什么想法吗?这是代码:
#define UNICODE
// includes...
int main( int argc, char * argv[] )
{
FILE * pzInFile,
* pzOutFile;
try
{
char sUtf8[8192];
char * pcDst = sUtf8;
wchar_t wsUtf16[8192];
_wfopen_s( & pzInFile, L"../config-sample.xml", L"r" );
_wfopen_s( & pzOutFile, L"../config-sample2.xml", L"w+" );
if( pzInFile && pzOutFile )
{
size_t uiRead;
while( uiRead = fread_s( pcDst, sizeof( sUtf8 ), 1, 1, pzInFile ) )
{
pcDst += uiRead;
}
size_t uiLen = pcDst - sUtf8;
sUtf8[uiLen] = 0;
MultiByteToWideChar( CP_UTF8, 0, sUtf8, 8192, wsUtf16, 8192 ); // UTF-8 to UTF-16
fwrite( wsUtf16, 1, uiLen, pzOutFile );
}
else
{
throw L"Failed to open file";
}
}
catch( const wchar_t * pwsMsg )
{
::MessageBox( NULL, pwsMsg, L"Error", MB_OK | MB_TOPMOST | MB_SETFOREGROUND );
}
if( pzInFile )
{
fclose( pzInFile );
pzInFile = 0;
}
if( pzOutFile )
{
fclose( pzOutFile );
pzOutFile = 0;
}
return 0;
}
最佳答案
我修改了您的代码以修复一些错误。 Notepad++ 在有或没有 BOM 的情况下都能正确显示输出文件,因此它的编码检测例程看起来很合理。
主要问题是:
0A
的双字节 UTF-16 字符将在 Windows 上被翻译为 0D 0A
.MultibyteToWideChar
返回转换的字符数,我使用 -1
作为输入缓冲区大小,因为它以 null 结尾。fwrite
需要为转换后的字符串写入具有正确字节数的转换后字符(减去空值)。在 UTF-16 中,一个字符是两个字节。至于您的文件损坏,最初 fwrite
正在写入等于 UTF-8 字符串长度的字节。因为那是 1-3 个字符,所以我得到的原始输出文件长度是 39 字节...对于 UTF-16 文件来说是不可能的,所以也许 Notepad++ 的编码启发式没有检测到 UTF-16。由于您没有提供示例数据,我做了一些,我的 Notepad++ 仍然检测到 UTF-16,因此启发式算法也可能会根据数据进行猜测。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
int main()
{
FILE* pzInFile;
FILE* pzOutFile;
try
{
char sUtf8[8192];
wchar_t wsUtf16[8192];
_wfopen_s(& pzInFile, L"config-sample.xml", L"r");
_wfopen_s(& pzOutFile, L"config-sample2.xml", L"w+b");
if(pzInFile && pzOutFile)
{
size_t uiRead = fread_s(sUtf8, sizeof(sUtf8), 1, sizeof(sUtf8) - 1, pzInFile);
sUtf8[uiRead] = 0;
int wlen = MultiByteToWideChar(CP_UTF8, 0, sUtf8, -1, wsUtf16, 8192); // UTF-8 to UTF-16
fwrite(wsUtf16, 1, (wlen-1) * sizeof(wchar_t), pzOutFile);
}
else
{
throw L"Failed to open file";
}
}
catch(const wchar_t* pwsMsg)
{
::MessageBox(NULL, pwsMsg, L"Error", MB_OK | MB_TOPMOST | MB_SETFOREGROUND);
}
if(pzInFile)
{
fclose(pzInFile);
pzInFile = 0;
}
if(pzOutFile)
{
fclose(pzOutFile);
pzOutFile = 0;
}
return 0;
}
我的数据文件包含:
<data>αßΓπΣσµτΦΘΩδ</data>
这是输入和输出文件的十六进制转储。请注意,由于我让输入文件以文本模式打开,因此在输入时 0D0A
CR-LF 组合被转换为仅 0A
,因此只有换行以二进制模式结束输出文件。我留下它来说明 Windows 文本与二进制问题。您可能应该以二进制模式打开两者。
input: 3C646174613ECEB1C39FCE93CF80CEA3CF83C2B5CF84CEA6CE98CEA9CEB43C2F646174613E0D0A0D0A
output: 3C0064006100740061003E00B103DF009303C003A303C303B500C403A6039803A903B4033C002F0064006100740061003E000A000A00
关于C++ 读取 UTF-8 文件 OK,转换为 UTF-16 OK,写回文件 NOT OK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18678879/
我正在使用以下代码读取我在文本编辑器 (Notepad++) 中创建的文本 (.xml) 文件,将我从中读取的 UTF-8 文本转换为 UTF-16,以便 Windows API 函数可以使用它,然后
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 1年前关闭。 Improve this
我知道所有的论坛都充满了这样的问题,但我尝试了几个钩子(Hook),但它们不起作用(或者我做的不好)。 所以,我有: main.cpp <- fawn.h <- connector.cpp (defe
这是我正在使用的一段代码。 当 items 为 null 时,ok(Object items) 方法在内部调用 Jersey 的 Response.ok() 方法。 MembershipReq
我在 Tcl/Tk 中有一个简单的窗口,点击确定按钮运行模拟。我正在使用 Linux。模拟完成后,窗口将被销毁。问题是在模拟运行时窗口仍然存在。我希望窗口在我点击确定按钮后消失。 我尝试使用 wm w
在我们的网络应用程序中,我将 Angular-Materials $mdDialog 与确认对象一起使用。是否可以将按钮的顺序从取消-确定更改为确定-取消?并将初始焦点设置为取消按钮?也许通过 CSS
这个问题在这里已经有了答案: 关闭10年前。 Possible Duplicate: Ternary conditional operator in Python 我有这个问题,不知道要问谷歌: (v
我尝试使用 R 进行回归。我有以下代码,导入 CSV 文件没有问题 dat <- read.csv('http://pastebin.com/raw.php?i=EWsLjKNN',sep="
在 QInputDialog 中,如何去掉 OK 和 Cancel 按钮中的图标? 注意取消和确定的图标。我查看了属性按钮,不知道如何删除它们。 最佳答案 解决方案的策略是先获取按钮,但是这些属于QD
当使用Postman测试项目时,任何POST方法,我收到的是200 OK而不是201 Created,并且subreddit不是在数据库中创建的,并且在控制台休眠中接收到以下内容:SELECT T1_
当使用Postman测试项目时,任何POST方法,我收到的是200 OK而不是201 Created,并且subreddit不是在数据库中创建的,并且在控制台休眠中接收到以下内容:SELECT T1_
我制作了一个安卓应用程序,可以从本地 wifi 网络传输语音。为了收听和流式传输,我使用 JNI 中的 Opus C API 进行解码,并使用 OpenSL Audio 进行读取。 我从 Servic
我有一个定义如下的 map : mapMeasures := make(map[time.Time]models.Measure, 0) 与 type Measure struct { Del
这里我的数据集是 pd我已将其拆分为训练和测试数据 pd_train1和 pd_train2 sku national_inv lead_time in_transit_qty forecas
我已经检查过有关此问题的其他问题,但由于问题似乎非常具体,因此它们没有帮助。 我有一个像这样的数据框(这只是一个简单的示例,下面提供了来自 dput() 的示例数据): year species ab
当我使用 anova_test() 函数(来自 rstatix 包)做双向重复测量方差分析时,出现错误: lm.fit(x, y, offset = offset, singular.ok = sin
我一直在尝试对数据集进行 2-Way 重复测量测试,年份和疫苗类型是自变量,覆盖率是因变量。我用代码运行它: sat = anova_test( data=SA, dv = coverage, w
奇遇 我是一个普通的大学生,尹成是我的名字。顾名思义,我和其他人一样,没有什么特别之处。然而,在某个偶然的机会下,我发现了一个全新的领域——编程。 初印象 说实话,我对编程并不了解,甚至可以说是一窍不
我使用这些代码创建了一个卡拉 OK 并将其刻录到 VCD。 xxxxxx_1.m4a 文件是左声道(乐器),xxxxxx_0.m4a 文件是右声道(带人声的歌曲)。 将它们组合到 become xxx
我不确定为什么会发生这种情况,但我有一个简单的 Ajax 代码: $.ajax({ url: "/javascript/testing.js"}) .done(function(data){
我是一名优秀的程序员,十分优秀!