我正在学习C并获得了一项任务,我们必须将纯文本转换为莫尔斯代码并返回。 (我对Java大多熟悉,所以请遵守我使用的条款。)
为此,我有一个包含所有字母字符串的数组。
char *letters[] = {
".- ", "-... ", "-.-. ", "-.. ", ".", "..-." etc
我写了一个函数来返回所需字母的位置。
int letter_nr(unsigned char c)
{
return c-97;
}
这是有效的,但是作业规范要求处理瑞典语上的字母åäö。瑞典语字母与最后用这三个字母的英语相同。我尝试检查这些,如下:
int letter_nr(unsigned char c)
{
if (c == 'å')
return 26;
if (c == 'ä')
return 27;
if (c == 'ö')
return 28;
return c-97;
}
不幸的是,当我尝试测试这个函数时,我得到了所有这三个函数的相同值:98。这是我的主要测试函数:
int main()
{
unsigned char letter;
while(1)
{
printf("Type a letter to get its position: ");
scanf("%c", &letter);
printf("%d\n", letter_nr(letter));
}
return 0;
}
我该怎么做才能解决这个问题?
答案 0 :(得分:10)
字符常量的编码实际上取决于您的语言环境设置。
最安全的选择是使用宽字符和相应的功能。您将字母表声明为const wchar_t* alphabet = L"abcdefghijklmnopqrstuvwxyzäöå"
,将单个字符声明为L'ö';
这个小示例程序适合我(也可以在UNIX控制台上使用UTF-8) - 试试吧。
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(int argc, char** argv)
{
wint_t letter = L'\0';
setlocale(LC_ALL, ""); /* Initialize locale, to get the correct conversion to/from wchars */
while(1)
{
if(!letter)
printf("Type a letter to get its position: ");
letter = fgetwc(stdin);
if(letter == WEOF) {
putchar('\n');
return 0;
} else if(letter == L'\n' || letter == L'\r') {
letter = L'\0'; /* skip newlines - and print the instruction again*/
} else {
printf("%d\n", letter); /* print the character value, and don't print the instruction again */
}
}
return 0;
}
示例会话:
Type a letter to get its position: a
97
Type a letter to get its position: A
65
Type a letter to get its position: Ö
214
Type a letter to get its position: ö
246
Type a letter to get its position: Å
197
Type a letter to get its position: <^D>
据我所知,在Windows上,这不适用于Unicode BMP之外的字符,但这不是问题。
答案 1 :(得分:2)
通常,编码内容非常复杂。另一方面,如果您只想要一个特定于您的编译器/平台的脏解决方案,而不是在您的代码中添加类似的东西:
printf("letter 0x%x is number %d\n", letter, letter_nr(letter));
它将为您的变音符号提供十六进制值。而不仅仅用if
语句替换你的字母数字。
编辑你说你总是得到98,所以你的scanf从控制台得到98 + 97 = 195 = 0x3C。根据这个table 0x3C是Latin1 block
中常见的 LATIN SMALL LETTER N WITH Something 的UTF8序列的开头。你在Mac OS X
?
编辑这是我的最后一次通话。非常hackery,但它适用于我:))
#include <stdio.h>
// scanf for for letter. Return position in Morse Table.
// Recognises UTF8 for swedish letters.
int letter_nr()
{
unsigned char letter;
// scan for the first time,
scanf("%c", &letter);
if(0xC3 == letter)
{
// we scanf again since this is UTF8 and two byte encoded character will come
scanf("%c", &letter);
//LATIN SMALL LETTER A WITH RING ABOVE = å
if(0xA5 == letter)
return 26;
//LATIN SMALL LETTER A WITH DIAERESIS = ä
if(0xA4 == letter)
return 27;
// LATIN SMALL LETTER O WITH DIAERESIS = ö
if(0xB6 == letter)
return 28;
printf("Unknown letter. 0x%x. ", letter);
return -1;
}
// is seems to be regular ASCII
return letter - 97;
} // letter_nr
int main()
{
while(1)
{
printf("Type a letter to get its position: ");
int val = letter_nr();
if(-1 != val)
printf("Morse code is %d.\n", val);
else
printf("Unknown Morse code.\n");
// strip remaining new line
unsigned char new_line;
scanf("%c", &new_line);
}
return 0;
}
答案 2 :(得分:0)
嗯...起初我会说“有趣”的角色不是char
。您不能将其中一个传递给接受char
参数的函数,并希望它能够正常工作。
试试这个(添加其余位):
char buf[100];
printf("Enter a string with funny characters: ");
fflush(stdout);
fgets(buf, sizeof buf, stdin);
/* now print it, as if it was a sequence of `char`s */
char *p = buf;
while (*p) {
printf("The character '%c' has value %d\n", *p, *p);
p++;
}
现在尝试使用宽字符:#include <wchar.h>
并将printf
替换为wprintf
,将fgets
替换为fgetws
等等。