我试过了:
char comando;
if( comando == 'ç' || comando == 'Ç') {
comando = 'c';
return comando;
}
但它给了我这个错误:“由于数据类型的范围有限,比较总是错误的。”
我无法确定我的老师要编译我的程序的GCC版本,但她会在Linux上运行它(可能是Ubuntu)。我不能使用标准的lib。 :(
谢谢!
答案 0 :(得分:3)
C标准表示诸如'ç'之类的字符常量是整数常量:
§6.4.4.4/ 9
整数字符常量的类型为int。整数字符常量的值 包含映射到单字节执行字符的单个字符是 解释为整数的映射字符表示的数值。
如果在您的机器上签署了char类型(它在Linux上),那么当comando
包含'ç'并且被提升为整数时,它将变为负整数,而'ç'是一个正整数。因此来自编译器的警告。
对于8位字符集,到目前为止,执行此类操作的最快方法是创建一个256字节的表,其中每个位置包含字符的非重音版本。
int unaccented(int c)
{
static const char map[256] =
{
'\x00', '\x01', ...
...
'0', '1', '2', ...
...
'A', 'B', 'C', ...
...
'a', 'b', 'c', ...
...
'A', 'A', 'A', ... // 0xC0 onwards...
...
'a', 'a', 'a', ... // 0xE0 onwards...
...
};
if (c < 0 || c > 255)
return EOF;
else
return map[c];
}
当然,你要编写一个程序 - 可能是一个脚本 - 来生成数据表,而不是手动完成。在0..127范围内,位置x处的字符是代码为x的字符(所以map['A'] == 'A'
)。
如果允许您使用C99,则可以使用指定的初始化程序来改进表格:
static const char map[] =
{
['\x00'] = '\x00', ...
['A'] = 'A', ...
['a'] = 'a', ...
['å'] = 'a', ...
['Å'] = 'A', ...
['ÿ'] = 'y', ...
};
你应该用 diphthongs 字母来做什么,例如'æ'或'ß'没有等效的ASCII;然而,“当有疑问时,不要改变它”的简单规则可以合理地应用。它们不是重音字符,但它们也不是ASCII字符。
这对UTF-8来说效果不佳。为此,您需要更多专门的表,这些表来自Unicode标准中的数据。
另请注意,在调用此函数之前,您应该将任何'char'值强制为'unsigned char'。也就是说,该代码也可能试图与滥用者打交道。但是,当人们在调用函数时不小心时,很难将'ÿ'(0xFF)与EOF区分开来。 C标准字符测试宏需要支持所有有效字符值(当转换为unsigned char时)和EOF作为输入 - 这遵循该设计。
§7.4/ 1
在所有情况下,参数都是一个int,其值应为 可表示为无符号字符或等于宏EOF的值。如果 参数有任何其他值,行为未定义。
答案 1 :(得分:3)
作为其他答案的补充,请尝试以下尺寸:
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
int main(int argc, char** argv)
{
wchar_t* x = calloc(100, sizeof(wchar_t));
char* y = calloc(100, sizeof(char));
printf("Input something: ");
fread(y, 1, 99, stdin);
mbstowcs(x, y, 100);
if ( x[0] = L'è' )
{
printf("Ohhh, french character!\n");
}
free(y); free(x);
return 0;
}
此代码向您展示了两件事:首先,如何将您读入的多字节字符串转换为宽字符串。从那里,你可以处理几乎所有存在的角色(理论上至少)。
完成此操作后,您只需要一个字符映射及其变换,这样您就可以解析每个字符并将其映射到其他字符。 请参阅此
的其他答案一些注意事项:我在输入输入时故意在stdin - ctrl + D上使用fread()
。这是为了防止缓冲区溢出攻击,如果将结果传递给函数,则容易使用scanf(参见NOP底座)。
其次,我盲目地假设y的输入主要是单字节。事实是,如果在多字节字符串中每个字符使用两个字节,则100个字符= 50个wchar_t字符。我也可以检查长度等,但这超出了本例的范围。
答案 2 :(得分:2)
你在另一个类似的问题中提到,这很容易用你知道的其他语言做。如果我是你并且找不到一个很好的方法来使用C中的可用代码并且需要在C中执行此操作,我会用另一种语言编写一个程序来生成一个C函数,它将为您进行转换。只要你可以循环遍历所有字符,这应该不会太困难,尽管它可能是大代码。我可能会为utf-16做这个,只需要一个简单的包装函数,它接受utf-8,将它们转换为utf-16,并调用转换函数。
转换函数只能由一个非常大的switch / case语句组成,默认情况下是没有转换的字符。