【发布时间】:2014-02-28 00:12:21
【问题描述】:
我正在为阿姆哈拉语(埃塞俄比亚广泛使用的语言之一)编写一个简单的 Caesar 实现。这是代码
main(){
setlocale(LC_ALL, " ");
int i, key=0;
wchar_t message[20];
wprintf(L"Enter message:>");
fgetws(message, sizeof(message), stdin);
wprintf(L"Enter cipher key:>");
wscanf(L"%d", &key);
/* basic input validation goes here */
for(i=0;message[i]!='\0'; i++){
message[i]=message[i]+key;
}
wprintf(L"The cipher is: %ls", message);
wprintf(L"\n");
return 0;
}
代码编译时没有警告。如果 key 小于或等于 5,则工作正常。当 key value 为 6 及以上时,问题就出现了。就我测试而言,它会打印一个额外的字符。我通过 gdb 运行它以查看它在哪里拾取额外的字符。但没有多大意义。这是我的问题:
- 为什么它对密钥 0 到 5 有效,但对以上无效?
- 它从哪里获得为大于 5 的密钥打印的额外字符?
如果它有助于我机器上的 wchar 大小为 4 字节。
谢谢
编辑:
样本输入:
message: ተደለ
key: 6
output: ቶዶሎ 0010
output I expect ቶዶሎ
0010 与 unicode 表中没有相应符号的字符一样显示。
再次感谢。
【问题讨论】:
-
编辑问题并添加消息、密钥和结果输出。还添加您期望获得的输出。
-
您的代码不包含字母表。在拉丁字母表中,如果您的偏移量为 3 并编码为
z,您应该得到一个c。使用您的代码,您将得到一个右大括号},它位于Unicode 表中z之后的三个位置。因此,在阿姆哈拉字母之后寻找 Unicode 范围内的奇怪字符。 (您还可以无条件地转换所有字符,无论它们是空格还是标点符号,这不利于格式良好的消息。) -
@Oehm,谢谢,但这将由输入验证处理;并最终将在一个单独的函数上进行加密,但我现在不明白的是为什么当密钥大于 5 时它会显示一个额外的字符并且对于小于 5 的密钥有效。
-
您看到的额外字符是宽字符换行符 (
0x0a),它保存在使用fgetws读取的字符串中,并且您用 6 个字符换行,从而产生0x10。这似乎不是一个可打印的字符——这就是终端决定将字符代码打印为普通十六进制数字的原因。在换行之前删除尾随的换行符或有条件地换行。 -
@Oehm,非常感谢您回答了我的问题。我不知道它也会在输入末尾替换换行符。我怎么能投票/接受你的回答?
标签: c localization wchar