如何在C++中正确地将我的语言字符输出到HTML文件中

How to output characters of my language to HTML file in C++ correctly?

本文关键字:输出 字符 文件 HTML 语言 C++ 正确地 我的      更新时间:2023-10-16

我试图将包含unicode字符的wstring变量输出到HTML文件,但问题是,当我通过web浏览器打开文件时,它显示的是奇怪的相似字符,而不是unicode字符(ANSI字符显示正确(。然而,如果我通过文本编辑器(例如记事本(打开文件,它会显示完全正确。此外,我需要输出某些货币字符,但它会中断以下所有输出(当然它本身不是输出的(。显然,这个问题只出现在C++输出中:如果我手动向HTML文件中写入一些内容,浏览器就会正确显示所有内容。

我一直在搜索关于这个问题的一些讨论,所有这些讨论都建议使用不同的设置语言环境的变量,但它只适用于控制台输出,而不适用于文件1。他们还建议设置"UTF-8 with BOM"编码,但它也不起作用。

以下是我的应用程序的一些行为示例。

这是我用C++输出的HTML代码:

<div class="table-head">
<div>Type</div>
<div>Name</div>
</div>
<div class="table-row">
<div>Системные устройства</div>
<div>Диспетчер томов</div>
</div>

以下是浏览器显示的内容:

型号名称

��������� ���������� ��������� �����

第二个例子与货币字符有关:这里是HTML文件中没有这个字符的另一部分:

<div class="table-row">
<div>Date Format</div>
<div>d MMMM yyyy &apos;г.&apos;</div>
</div>
<div class="table-row">
<div>Time Format Specifier</div>
<div>24-hour format</div>
</div>

浏览器输出:

日期格式d MMMM yyyy'�.'

时间格式指定器24小时格式

正如你所看到的,我的语言中有一个字符"Γ",它仍然被错误地输出。但回到示例:让我们在HTML文件中添加一个新的容器(当然使用C++i/o代码(,它与其他两个容器类似,并且包含货币字符"₽"。结果如下:

<div class="table-row">
<div>Date Format</div>
<div>d MMMM yyyy &apos;г.&apos;</div>
</div>
<div class="table-row">
<div>Currency</div>
<div>

这是文件的末尾,例如,由于货币字符中断,必须输出的其余数据丢失。您可以猜测浏览器的输出结果。

我展示了如何从上一个例子中获得"日期格式"值以及如何输出它的具体例子

#include <Windows.h>
...
TCHAR temp[STRINGSIZE];
constexpr int length = STRINGSIZE;
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, temp, length);
_tcscpy_s(m_SysInfoStruct.m_strDateFormat, temp);
...

其中m_SysInfoStruct.m_strDateFormat具有TCHAR[]类型。

这是输出过程:

#include <Windows.h>
...
#ifdef UNICODE
#define tofstream std::wofstream
#else
#define tofstream std::ofstream
#endif
...
using tstring = std::basic_string<TCHAR>;
...
tofstream outputFile("somehtmlfile.html");
outputFile << getHTMLReport();
outputFile.close();
...

以下事件发生在getHTMLReport((中:

...
tstring czTemp(_T(""));
czTemp.append(_T("<"));
czTemp.append(_T("div"));
czTemp.append(_T(">"));
czTemp.append(m_SysInfoStruct.m_strDateFormat);
czTemp.append(_T("</"));
czTemp.append(_T("div"));
czTemp.append(_T(">n"));
m_sHTMLData += czTemp;
...
return m_sHTMLData;

它或多或少是这样的。

std::wofstream提供了UTF16接口,这在很多方面都令人头疼。

您想要使用std::ofstream的UTF8接口。如果您在Windows中执行此操作,那么您很可能会从Windows I/O函数获得UTF16输入。您希望将UTF16转换为UTF8,然后写入std::ofstream。您可以考虑避免使用那些T宏,因为它们往往只会使事情复杂化。

示例:

#include <iostream>
#include <fstream>
#include <io.h> 
#include <fcntl.h> 
#include <windows.h>
std::string get_utf8(const std::wstring &wstr)
{
if(wstr.empty()) return std::string();
int sz = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], -1, 0, 0, 0, 0);
std::string res(sz, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], -1, &res[0], sz, 0, 0);
return res;
}
int main()
{
std::wstring html = L"<!DOCTYPE html><html><body>";
html += L"Системные устройства";
html += L"</html></body>";
std::string utf8 = get_utf8(html);
std::ofstream outputFile("test.html");
outputFile << utf8;
outputFile.close();
return 0;
}