如何解决如何将 C 字符数组中的变音符号转换为十六进制代码?
我的任务是将包含多个变音符号的字符数组转换为具有相应 ANSI 十六进制代码的字符数组,以便在终端中正确显示它。
ASCII ANSI
- 'Ä' 0x8E
- 'ä' 0x84
- 'Ö' 0x99
- 'ö' 0x94
- 'Ü' 0x9A
- 'ü' 0x81
- 'ß' 0xE1
我的尝试看起来像这样:
#include <iostream>
using namespace std;
int main()
{
char lied[] = "ÄäÖöÜüß\r\n"; // this syntax must remain the same
cout << lied << endl;
for (char* p = lied; *p != '\0'; ++p)
{
char c;
switch (*p)
{
case 'Ä': c = '\x8e'; break;
case 'ä': c = '\x84'; break;
case 'Ö': c = '\x99'; break;
case 'ö': c = '\x94'; break;
case 'Ü': c = '\x9a'; break;
case 'ü': c = '\x81'; break;
case 'ß': c = '\xe1'; break;
default:
c = *p;
break;
}
*p = c;
}
cout << lied << endl;
}
显然我的解决方案不起作用,因为我发现无法以这种方式比较字符。似乎每个变音符号都由数组中的 2 个字符组成(它们都具有负值)。如果我是对的,需要将变音符号解释为无符号字符,因为它们需要更多内存来表示其他符号。 如何使用 C 风格的字符数组和指针来做到这一点?
(除了 C++ 输入/输出流,我只允许使用基本的 C)
我什至可以简单地覆盖变音,还是应该在循环时直接输出字符并在必要时替换它们? 我更喜欢先尝试第一种方法。
解决方法
你的问题不是很友好,因为它没有直接给出重要的东西。我可以从细节中猜到最多:
您的 ASCII ANSI 表显示您需要对以下字符 ÄäÖöÜüß
似乎每个变音符号都由数组中的 2 个字符组成(它们都有负值):这意味着您的源文件当前是 UTF-8 编码的。
这里是您需要的翻译表:
char utf-8 cp850
Ä "\xc3\x84" "\x8e"
ä "\xc3\xa4" "\x84"
Ö "\xc3\x96" "\x99"
ö "\xc3\xb6" "\x94"
Ü "\xc3\x9c" "\x9a"
ü "\xc3\xbc" "\x81"
ß "\xc3\x9f" "\xe1"
我将您的代码更改为:
#include <iostream>
using namespace std;
int main()
{
char lied[] = "ÄäÖöÜüß\r\n"; // this syntax must remain the same
cout << lied << endl;
int second = 0;
char *q = lied;
for (char* p = lied; *p != '\0'; ++p)
{
if (*p == '\xc3') {
second = 1;
}
else if (second) {
char c;
second = 0;
switch (*p)
{
case '\x84': c = '\x8e'; break;
case '\xa4': c = '\x84'; break;
case '\x96': c = '\x99'; break;
case '\xb6': c = '\x94'; break;
case '\x9c': c = '\x9a'; break;
case '\xbc': c = '\x81'; break;
case '\x9f': c = '\xe1'; break;
default:
c = *p;
break;
}
*q++ = c;
}
else {
*q++ = *p;
}
}
*q = 0;
cout << lied << endl;
return 0;
}
在我的 Windows 系统上的 CP850 控制台中,我得到了预期的结果:
├ä├ñ├û├Â├£├╝├ƒ
ÄäÖöÜüß
,
我猜当您说“我想将变音符号转换为十六进制代码”时,您的意思是您想要字符串的 C 字符串表示形式,其中一些字符被编码为转义序列。
让我们这样做并处理以下字符:
- 基本转义序列:诸如制表符 (
\t
) 之类的特殊字符被编码为反斜杠加一个字母。 - 十六进制转义字符:所有其他不在 32 到 127 之间有效 ASCII 范围内的字符都被编码为类似
\xc0
的序列。
这些转义使字符串变长,因此您无法对字符串进行适当的编码。创建另一个字符串,该字符串至少可以容纳原始字符串长度的四倍加上空终止符的一倍。
现在遍历原始字符串并进行转换:
#include <stdio.h>
int main(void)
{
char lied[] = "\"Fix Schwyz!\" quäkt Jürgen blöd vom Paß.\r\n";
char encoded[4 * sizeof(lied)];
const char *p = lied;
char *q = encoded;
while (*p) {
unsigned char c = *p++;
switch (c) {
case '"': *q++ = '\\'; *q++ = '"'; break;
case '\r': *q++ = '\\'; *q++ = 'r'; break;
case '\n': *q++ = '\\'; *q++ = 'n'; break;
case '\t': *q++ = '\\'; *q++ = 't'; break;
case '\a': *q++ = '\\'; *q++ = 'a'; break;
case '\b': *q++ = '\\'; *q++ = 'b'; break;
default: if (c < 32 || c > 127) {
static const char *hex = "0123456789abcdef";
*q++ = '\\';
*q++ = 'x';
*q++ = hex[c / 16];
*q++ = hex[c % 16];
} else {
*q++ = c;
}
}
}
*q = '\0';
puts(encoded);
return 0;
}
在使用 Latin1 (ISO-8859-1) 编码的语言环境中,这将打印:
\"Fix Schwyz!\" qu\xe4kt J\xfcrgen bl\xf6d vom Pa\xdf.\r\n
在 UTF-8 语言环境中,您应该会看到每个非 ASCII 字符的 hwo 转义十六进制代码。
注意事项:
- 对于此解决方案,您不需要知道变音符号的确切代码,它们只是“非 ASCII”,就像其他重音字符或外来字符一样。
- 这个解决方案不关心编码,只要给出一串字符即可。
- 您的原始代码是 C++,因此您无需自己进行繁琐的分配计算,而是可以创建一个
std::string
并附加到它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。