简体   繁体   English

小写到大写

[英]Lower case to upper case

How to convert lower case ASCII char into upper case using a bitmask (no -32 allowed)? 如何使用位掩码将小写ASCII字符转换为大写(不允许-32)?

I'm not asking for solving my homework, only some hints. 我不是要求解决我的作业,只是提示。

Thanks 谢谢

As you state "(no -32 allowed)", I guess you know that the difference between lower case characters and upper case characters is 32. Now convert 32 to its binary representation, there's only one bit set. 当你说“(不允许-32)”时,我想你知道小写字符和大写字符之间的区别是32.现在将32转换为它的二进制表示,只有一个位设置。 After that, work out a way to use a bit mask to switch the bit. 之后,找出一种使用位掩码来切换位的方法。

Think about the differential between lower and upper case (0x20) and then apply the appropriate mask to your value 考虑大小写(0x20)之间的差异,然后将适当的掩码应用于您的值

XOR to get lower from upper or upper from lower 异或从上部或上部降低

对于实际代码,您应该是库函数,例如toupper()或towupper(),或者能够处理Unicode复杂性的东西。

Just translate +-32 into a bit operation. 只需将+-32转换为位操作即可。 32 can be written as 2^x . 32可以写成2^x

This example assumes that the string is in ASCII, and using the English alphabet. 此示例假定字符串是ASCII,并使用英文字母。

This is C99 C code, you should use the proper compiler flag to set this when compiling. 这是C99 C代码,您应该在编译时使用正确的编译器标志来设置它。 I specifically tried not to use any libs in this example, standard or not because I'm guessing you're still in the process of learning the basics of C programming. 我特意尝试不使用本例中的任何库,标准与否,因为我猜你还在学习C编程的基础知识。

#define UPPER_CASE_SWITCH 0x5f
void makeUpper(unsigned char *string, int length)
{
    for(char c; length != 0 && (c=*string) != 0; --length) 
        *string++ = (((c >= 'a' && c <= 'z')) ? (c & UPPER_CASE_SWITCH) : c);
}

It takes advantage of the fact that the ONLY difference between an upper and a lower case character in the ASCII table, is a single bit. 它利用了以下事实:ASCII表中的大写和小写字符之间的唯一差异是单个位。 Specifically the 6th bit (from the right.) All we have to do is create a "mask" that contains all 1's except for the 6th bit (from the right) and then use the binary AND instruction (&) to apply this mask to our character. 特别是第6位(从右边开始)。我们所要做的就是创建一个“掩码”,其中包含除第6位(右起)之外的所有1,然后使用二进制AND指令(&)将此掩码应用于我们的性格。 And then of course put this into our string. 然后当然把它放到我们的字符串中。

Here is a python example. 这是一个python示例。

>>> bin(ord("a")) ## Gets the binary digit for the letter "a"
'0b1100001'
>>> bin(ord("A")) ## Gets the binary digit for the letter "A"
'0b1000001'
>>> hex(0b1011111) ## Gets the hexadecimal mask we are using in the C source
'0x5f'

In my opinion, this is the best way to make an ASCII string (or a single ASCII character) upper case in c. 在我看来,这是在c中制作ASCII字符串(或单个ASCII字符)大写的最佳方法。 Unless, of course you want something that will return a new string, ie you want to create an upper-case version of the "old" string but still be able to keep the original version somewhere. 当然,除非你想要一些会返回一个新字符串的东西,即你想要创建一个“旧”字符串的大写版本,但仍然能够将原始版本保留在某处。 This shouldn't be too hard to do, if you understand my first example. 如果您理解我的第一个例子,这应该不会太难。 You just have to allocate a new array to put the upper-case string in, and return a pointer to this array (unsigned char*). 您只需分配一个新数组来放入大写字符串,并返回指向此数组的指针(unsigned char *)。

Compare the hexadecimal values of lower case ASCII characters to upper case ASCII characters and the solution should become clear. 将小写ASCII字符的十六进制值与大写ASCII字符进行比较,解决方案应该变得清晰。 It may also be helpful to compare the binary values if the solution is not evident right away. 如果解决方案不是很明显,那么比较二进制值也可能有帮助。

从一个小拉丁字母的ASCII码中减去32的操作将第5位从1翻转到0。

As you specify this, your homework is not well defined. 在您指定时,您的作业没有明确定义。 The C standard knows nothing about a particular encoding of the source or execution character set, in particular it doesn't assume anything that comes close to ASCII or so. C标准对源或执行字符集的特定编码一无所知,特别是它不假设任何接近ASCII的东西。

So wnoise was right, the only standard way to deal with these things are the predefined functions and macros that are provided for such an effect. 所以wnoise是对的,处理这些事情的唯一标准方法是为这种效果提供的预定义函数和宏。

尝试使用0xDF(十六进制)或011011111二进制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM