我目前正在编写一个涉及数学的 C++ 程序。因此,我试图将某些对象表示为在其类的 wstring 成员变量中具有下标数字。然而,以任何容量存储这些字符的尝试都会迫使它们成为非下标对应物。相比之下,粘贴在代码中的字符的直接使用可以根据需要保留。以下是我试验过的几种情况:
setlocale(LC_ALL, "");
wchar_t txt = L'\u2080';
wcout << txt << endl;
myfile << txt << endl;
Run Code Online (Sandbox Code Playgroud)
这将向文件和控制台输出“0”。
setlocale(LC_ALL, "");
wcout << L"x??" << endl;
myfile << L"x??" << endl;
Run Code Online (Sandbox Code Playgroud)
这会将“x01”输出到文件和控制台。
setlocale(LC_ALL, "");
wcout << "x??" << endl;
myfile << "x??" << endl;
Run Code Online (Sandbox Code Playgroud)
这输出“xâ'?â'?” 到控制台,如果可能的话我想避免,还有“x??” 到我想要的文件。理想的程序状态是将属性输出到文件和控制台的状态,但如果不可能,那么最好将非下标字符打印到控制台。
我的代码打算将整数转换为其相应的下标。我如何尽可能顺利地操纵这些字符而不将它们转换回来?我怀疑字符编码起了一定作用,但我不知道如何将 Unicode 编码合并到我的程序中。
我发现这些事情很棘手,我不确定它是否适用于每个 Windows 版本和区域设置的每个人,但这对我来说很有效:
\n\n#include <Windows.h>\n#include <io.h> // _setmode\n#include <fcntl.h> // _O_U16TEXT\n\n#include <clocale> // std::setlocale \n#include <iostream>\n\n// Unicode UTF-16, little endian byte order (BMP of ISO 10646)\nconstexpr char CP_UTF_16LE[] = ".1200";\n\nconstexpr wchar_t superscript(int v) {\n constexpr wchar_t offset = 0x2070; // superscript zero as offset\n if (v == 1) return 0x00B9; // special case\n if (v == 2 || v == 3) return 0x00B0 + v; // special case 2\n return offset + v;\n}\n\nconstexpr wchar_t subscript(int v) {\n constexpr wchar_t offset = 0x2080; // subscript zero as offset\n return offset + v;\n}\n\nint main() {\n // set these before doing any other output:\n setlocale(LC_ALL, CP_UTF_16LE);\n _setmode(_fileno(stdout), _O_U16TEXT);\n\n // subscript\n for (int i = 0; i < 10; ++i)\n std::wcout << L\'X\' << subscript(i) << L\' \';\n std::wcout << L\'\\n\';\n\n // superscript\n for (int i = 0; i < 10; ++i)\n std::wcout << L\'X\' << superscript(i) << L\' \';\n std::wcout << L\'\\n\'; \n}\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\nX\xe2\x82\x80 X\xe2\x82\x81 X\xe2\x82\x82 X\xe2\x82\x83 X\xe2\x82\x84 X\xe2\x82\x85 X\xe2\x82\x86 X\xe2\x82\x87 X\xe2\x82\x88 X\xe2\x82\x89\nX\xe2\x81\xb0 X\xc2\xb9 X\xc2\xb2 X\xc2\xb3 X\xe2\x81\xb4 X\xe2\x81\xb5 X\xe2\x81\xb6 X\xe2\x81\xb7 X\xe2\x81\xb8 X\xe2\x81\xb9\nRun Code Online (Sandbox Code Playgroud)\n\n更方便的方法可能是wstring直接创建 s。这里wsupandwsub接受 awstring并返回转换后的wstring。他们无法处理的角色将保持不变。
#include <Windows.h>\n#include <io.h> // _setmode\n#include <fcntl.h> // _O_U16TEXT\n\n#include <algorithm> // std::transform\n#include <clocale> // std::setlocale \n#include <iostream>\n\n// Unicode UTF-16, little endian byte order (BMP of ISO 10646)\nconstexpr char CP_UTF_16LE[] = ".1200";\n\nstd::wstring wsup(const std::wstring& in) {\n std::wstring rv = in;\n\n std::transform(rv.begin(), rv.end(), rv.begin(),\n [](wchar_t ch) -> wchar_t {\n // 1, 2 and 3 can be put in any order you like\n // as long as you keep them in the top section\n if (ch == L\'1\') return 0x00B9;\n if (ch == L\'2\') return 0x00B2;\n if (ch == L\'3\') return 0x00B3;\n\n // ...but this must be here in the middle:\n if (ch >= \'0\' && ch <= \'9\') return 0x2070 + (ch - L\'0\');\n\n // put the below in any order you like,\n // in the bottom section\n if (ch == L\'i\') return 0x2071;\n if (ch == L\'+\') return 0x207A;\n if (ch == L\'-\') return 0x207B;\n if (ch == L\'=\') return 0x207C;\n if (ch == L\'(\') return 0x207D;\n if (ch == L\')\') return 0x207E;\n if (ch == L\'n\') return 0x207F;\n\n return ch; // no change\n });\n return rv;\n}\n\nstd::wstring wsub(const std::wstring& in) {\n std::wstring rv = in;\n\n std::transform(rv.begin(), rv.end(), rv.begin(),\n [](wchar_t ch) -> wchar_t {\n if (ch >= \'0\' && ch <= \'9\') return 0x2080 + (ch - L\'0\');\n if (ch == L\'+\') return 0x208A;\n if (ch == L\'-\') return 0x208B;\n if (ch == L\'=\') return 0x208C;\n if (ch == L\'(\') return 0x208D;\n if (ch == L\')\') return 0x208E;\n if (ch == L\'a\') return 0x2090;\n if (ch == L\'e\') return 0x2091;\n if (ch == L\'o\') return 0x2092;\n if (ch == L\'x\') return 0x2093;\n if (ch == 0x0259) return 0x2094; // small letter schwa: \xc9\x99\n if (ch == L\'h\') return 0x2095;\n if (ch >= \'k\' && ch <= \'n\') return 0x2096 + (ch - \'k\');\n if (ch == L\'p\') return 0x209A;\n if (ch == L\'s\') return 0x209B;\n if (ch == L\'t\') return 0x209C;\n\n return ch; // no change\n });\n return rv;\n}\n\nint main() {\n std::setlocale(LC_ALL, CP_UTF_16LE);\n if (_setmode(_fileno(stdout), _O_U16TEXT) == -1) return 1;\n\n auto pstr = wsup(L"0123456789 +-=() ni");\n auto bstr = wsub(L"0123456789 +-=() aeox\xc9\x99 hklmnpst");\n\n std::wcout << L"superscript: " << pstr << L\'\\n\';\n std::wcout << L"subscript: " << bstr << L\'\\n\';\n\n std::wcout << L"an expression: x" << wsup(L"(n-1)") << L\'\\n\';\n}\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\nsuperscript: \xe2\x81\xb0\xc2\xb9\xc2\xb2\xc2\xb3\xe2\x81\xb4\xe2\x81\xb5\xe2\x81\xb6\xe2\x81\xb7\xe2\x81\xb8\xe2\x81\xb9 \xe2\x81\xba\xe2\x81\xbb\xe2\x81\xbc\xe2\x81\xbd\xe2\x81\xbe \xe2\x81\xbf\xe2\x81\xb1\nsubscript: \xe2\x82\x80\xe2\x82\x81\xe2\x82\x82\xe2\x82\x83\xe2\x82\x84\xe2\x82\x85\xe2\x82\x86\xe2\x82\x87\xe2\x82\x88\xe2\x82\x89 \xe2\x82\x8a\xe2\x82\x8b\xe2\x82\x8c\xe2\x82\x8d\xe2\x82\x8e \xe2\x82\x90\xe2\x82\x91\xe2\x82\x92\xe2\x82\x93\xe2\x82\x94 \xe2\x82\x95\xe2\x82\x96\xe2\x82\x97\xe2\x82\x98\xe2\x82\x99\xe2\x82\x9a\xe2\x82\x9b\xe2\x82\x9c\nan expression: x\xe2\x81\xbd\xe2\x81\xbf\xe2\x81\xbb\xc2\xb9\xe2\x81\xbe\nRun Code Online (Sandbox Code Playgroud)\n\n我的控制台无法显示hklmnpst- 的下标版本,但显然转换是正确的,因为复制/粘贴后它可以正常显示在此处。
| 归档时间: |
|
| 查看次数: |
715 次 |
| 最近记录: |