我发现这些事情很棘手,我从来不确定它是否适用于每个 Windows 版本和语言环境,但对我来说这样做很管用:
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <clocale>
#include <iostream>
constexpr char CP_UTF_16LE[] = ".1200";
constexpr wchar_t superscript(int v) {
constexpr wchar_t offset = 0x2070;
if (v == 1) return 0x00B9;
if (v == 2 || v == 3) return 0x00B0 + v;
return offset + v;
}
constexpr wchar_t subscript(int v) {
constexpr wchar_t offset = 0x2080;
return offset + v;
}
int main() {
setlocale(LC_ALL, CP_UTF_16LE);
_setmode(_fileno(stdout), _O_U16TEXT);
for (int i = 0; i < 10; ++i)
std::wcout << L'X' << subscript(i) << L' ';
std::wcout << L'\n';
for (int i = 0; i < 10; ++i)
std::wcout << L'X' << superscript(i) << L' ';
std::wcout << L'\n';
}
输出:
X₀ X₁ X₂ X₃ X₄ X₅ X₆ X₇ X₈ X₉
X⁰ X¹ X² X³ X⁴ X⁵ X⁶ X⁷ X⁸ X⁹
更方便的方法可能是直接创建wstring
。这里,wsup
和wsub
接受一个wstring
并返回一个转换后的wstring
。它们无法处理的字符将保持不变。
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <algorithm>
#include <clocale>
#include <iostream>
constexpr char CP_UTF_16LE[] = ".1200";
std::wstring wsup(const std::wstring& in) {
std::wstring rv = in;
std::transform(rv.begin(), rv.end(), rv.begin(),
[](wchar_t ch) -> wchar_t {
if (ch == L'1') return 0x00B9;
if (ch == L'2') return 0x00B2;
if (ch == L'3') return 0x00B3;
if (ch >= '0' && ch <= '9') return 0x2070 + (ch - L'0');
if (ch == L'i') return 0x2071;
if (ch == L'+') return 0x207A;
if (ch == L'-') return 0x207B;
if (ch == L'=') return 0x207C;
if (ch == L'(') return 0x207D;
if (ch == L')') return 0x207E;
if (ch == L'n') return 0x207F;
return ch;
});
return rv;
}
std::wstring wsub(const std::wstring& in) {
std::wstring rv = in;
std::transform(rv.begin(), rv.end(), rv.begin(),
[](wchar_t ch) -> wchar_t {
if (ch >= '0' && ch <= '9') return 0x2080 + (ch - L'0');
if (ch == L'+') return 0x208A;
if (ch == L'-') return 0x208B;
if (ch == L'=') return 0x208C;
if (ch == L'(') return 0x208D;
if (ch == L')') return 0x208E;
if (ch == L'a') return 0x2090;
if (ch == L'e') return 0x2091;
if (ch == L'o') return 0x2092;
if (ch == L'x') return 0x2093;
if (ch == 0x0259) return 0x2094;
if (ch == L'h') return 0x2095;
if (ch >= 'k' && ch <= 'n') return 0x2096 + (ch - 'k');
if (ch == L'p') return 0x209A;
if (ch == L's') return 0x209B;
if (ch == L't') return 0x209C;
return ch;
});
return rv;
}
int main() {
std::setlocale(LC_ALL, CP_UTF_16LE);
if (_setmode(_fileno(stdout), _O_U16TEXT) == -1) return 1;
auto pstr = wsup(L"0123456789 +-=() ni");
auto bstr = wsub(L"0123456789 +-=() aeoxə hklmnpst");
std::wcout << L"superscript: " << pstr << L'\n';
std::wcout << L"subscript: " << bstr << L'\n';
std::wcout << L"an expression: x" << wsup(L"(n-1)") << L'\n';
}
输出:
superscript: ⁰¹²³⁴⁵⁶⁷⁸⁹ ⁺⁻⁼⁽⁾ ⁿⁱ
subscript: ₀₁₂₃₄₅₆₇₈₉ ₊₋₌₍₎ ₐₑₒₓₔ ₕₖₗₘₙₚₛₜ
an expression: x⁽ⁿ⁻¹⁾
我的控制台无法显示hklmnpst
的下标版本 - 但显然转换是正确的,因为在复制/粘贴后它在这里正常显示。