- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正在阅读“The C Programming Language 2nd edition”,我对这个练习不太清楚:
Functions like isupper can be implemented to save space or to save time. Explore both possibilities.
如果能给我一些建议,我将不胜感激。
最佳答案
一个版本使用一个用适当值初始化的数组,代码集中每个字符一个字节(加 1 以允许 EOF,它也可以传递给分类函数):
static const char bits[257] = { ...initialization... };
int isupper(int ch)
{
assert(ch == EOF || (ch >= 0 && ch <= 255));
return((bits+1)[ch] & UPPER_MASK);
}
请注意,“位”可由所有各种函数使用,如 isupper()
、 islower()
、 isalpha()
等,并为掩码设置适当的值。如果您使“位”数组在运行时可变,则可以适应不同的(单字节)代码集。
这需要空间——数组。
另一个版本假设大写字符的连续性,以及有限的有效大写字符集(对 ASCII 没问题,对 ISO 8859-1 或其相关标准不太好):
int isupper(int ch)
{
return (ch >= 'A' && ch <= 'Z'); // ASCII only - not a good implementation!
}
这可以(几乎)用宏来实现;很难避免对字符进行两次评估,这在标准中实际上是不允许的。使用非标准 (GNU) 扩展,它可以实现为仅对字符参数求值一次的宏。将其扩展到 ISO 8859-1 需要第二个条件,即:
int isupper(int ch)
{
return ((ch >= 'A' && ch <= 'Z')) || (ch >= 0xC0 && ch <= 0xDD));
}
经常将其作为宏重复,由于位掩码具有固定大小,“空间节省”很快成为一种成本。
鉴于现代代码集的要求,映射版本在实践中几乎无一异常(exception)地被使用;它可以在运行时适应当前代码集等,而基于范围的版本则不能。
I still can't figure out how UPPER_MASK works. Can you explain it more specifically?
忽略 header 中符号的命名空间问题,您有一系列十二个分类宏:
isalpha()
isupper()
islower()
isalnum()
isgraph()
isprint()
iscntrl()
isdigit()
isblank()
isspace()
ispunct()
isxdigit()
isspace()
和isblank()
的区别是:
isspace()
—空格 (' '
)、换页符 ('\f'
)、换行符 ('\n'
)、回车符 ('\r'
)、水平制表符 ('\t'
) 和垂直制表符 ('\v'
< )/li>isblank()
— 空格 ( ' '
) 和水平制表符 ( '\t'
)。C 标准中有这些字符集的定义,以及 C 语言环境的指南。
例如(在 C 语言环境中),如果 islower()
为真,则 isupper()
或 isalpha()
为真,但在其他语言环境中则不必为真。
我认为必要的部分是:
DIGIT_MASK
XDIGT_MASK
ALPHA_MASK
LOWER_MASK
UPPER_MASK
PUNCT_MASK
SPACE_MASK
PRINT_MASK
CNTRL_MASK
BLANK_MASK
从这十个面具,你可以创建另外两个:
从表面上看,您也可以使用 ALPHA_MASK = UPPER_MASK | LOWER_MASK
,但在某些语言环境中,存在既不是大写也不是小写的字母字符。
因此,我们可以如下定义掩码:
enum CTYPE_MASK {
DIGIT_MASK = 0x0001,
XDIGT_MASK = 0x0002,
LOWER_MASK = 0x0004,
UPPER_MASK = 0x0008,
ALPHA_MASK = 0x0010,
PUNCT_MASK = 0x0020,
SPACE_MASK = 0x0040,
PRINT_MASK = 0x0080,
CNTRL_MASK = 0x0100,
BLANK_MASK = 0x0200,
ALNUM_MASK = ALPHA_MASK | DIGIT_MASK,
GRAPH_MASK = ALNUM_MASK | PUNCT_MASK
};
extern unsigned short ctype_bits[];
字符集的数据;显示的数据适用于 ISO 8859-1 的前半部分,但与所有 8859-x 代码集的前半部分相同。我使用 C99 指定的初始值设定项作为文档辅助,即使条目都是按顺序排列的:
unsigned short ctype_bits[] =
{
[EOF +1] = 0,
['\0' +1] = CNTRL_MASK,
['\1' +1] = CNTRL_MASK,
['\2' +1] = CNTRL_MASK,
['\3' +1] = CNTRL_MASK,
['\4' +1] = CNTRL_MASK,
['\5' +1] = CNTRL_MASK,
['\6' +1] = CNTRL_MASK,
['\a' +1] = CNTRL_MASK,
['\b' +1] = CNTRL_MASK,
['\t' +1] = CNTRL_MASK|SPACE_MASK|BLANK_MASK,
['\n' +1] = CNTRL_MASK|SPACE_MASK,
['\v' +1] = CNTRL_MASK|SPACE_MASK,
['\f' +1] = CNTRL_MASK|SPACE_MASK,
['\r' +1] = CNTRL_MASK|SPACE_MASK,
['\x0E'+1] = CNTRL_MASK,
['\x0F'+1] = CNTRL_MASK,
['\x10'+1] = CNTRL_MASK,
['\x11'+1] = CNTRL_MASK,
['\x12'+1] = CNTRL_MASK,
['\x13'+1] = CNTRL_MASK,
['\x14'+1] = CNTRL_MASK,
['\x15'+1] = CNTRL_MASK,
['\x16'+1] = CNTRL_MASK,
['\x17'+1] = CNTRL_MASK,
['\x18'+1] = CNTRL_MASK,
['\x19'+1] = CNTRL_MASK,
['\x1A'+1] = CNTRL_MASK,
['\x1B'+1] = CNTRL_MASK,
['\x1C'+1] = CNTRL_MASK,
['\x1D'+1] = CNTRL_MASK,
['\x1E'+1] = CNTRL_MASK,
['\x1F'+1] = CNTRL_MASK,
[' ' +1] = SPACE_MASK|PRINT_MASK|BLANK_MASK,
['!' +1] = PUNCT_MASK|PRINT_MASK,
['"' +1] = PUNCT_MASK|PRINT_MASK,
['#' +1] = PUNCT_MASK|PRINT_MASK,
['$' +1] = PUNCT_MASK|PRINT_MASK,
['%' +1] = PUNCT_MASK|PRINT_MASK,
['&' +1] = PUNCT_MASK|PRINT_MASK,
['\'' +1] = PUNCT_MASK|PRINT_MASK,
['(' +1] = PUNCT_MASK|PRINT_MASK,
[')' +1] = PUNCT_MASK|PRINT_MASK,
['*' +1] = PUNCT_MASK|PRINT_MASK,
['+' +1] = PUNCT_MASK|PRINT_MASK,
[',' +1] = PUNCT_MASK|PRINT_MASK,
['-' +1] = PUNCT_MASK|PRINT_MASK,
['.' +1] = PUNCT_MASK|PRINT_MASK,
['/' +1] = PUNCT_MASK|PRINT_MASK,
['0' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['1' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['2' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['3' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['4' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['5' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['6' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['7' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['8' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
['9' +1] = DIGIT_MASK|PRINT_MASK|XDIGT_MASK,
[':' +1] = PUNCT_MASK|PRINT_MASK,
[';' +1] = PUNCT_MASK|PRINT_MASK,
['<' +1] = PUNCT_MASK|PRINT_MASK,
['=' +1] = PUNCT_MASK|PRINT_MASK,
['>' +1] = PUNCT_MASK|PRINT_MASK,
['?' +1] = PUNCT_MASK|PRINT_MASK,
['@' +1] = PUNCT_MASK|PRINT_MASK,
['A' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['B' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['C' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['D' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['E' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['F' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK|XDIGT_MASK,
['G' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['H' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['I' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['J' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['K' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['L' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['M' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['N' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['O' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['P' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['Q' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['R' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['S' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['T' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['U' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['V' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['W' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['X' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['Y' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['Z' +1] = ALPHA_MASK|UPPER_MASK|PRINT_MASK,
['[' +1] = PUNCT_MASK|PRINT_MASK,
['\\' +1] = PUNCT_MASK|PRINT_MASK,
[']' +1] = PUNCT_MASK|PRINT_MASK,
['^' +1] = PUNCT_MASK|PRINT_MASK,
['_' +1] = PUNCT_MASK|PRINT_MASK,
['`' +1] = PUNCT_MASK|PRINT_MASK,
['a' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['b' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['c' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['d' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['e' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['f' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK|XDIGT_MASK,
['g' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['h' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['i' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['j' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['k' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['l' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['m' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['n' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['o' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['p' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['q' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['r' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['s' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['t' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['u' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['v' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['w' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['x' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['y' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['z' +1] = ALPHA_MASK|LOWER_MASK|PRINT_MASK,
['{' +1] = PUNCT_MASK|PRINT_MASK,
['|' +1] = PUNCT_MASK|PRINT_MASK,
['}' +1] = PUNCT_MASK|PRINT_MASK,
['~' +1] = PUNCT_MASK|PRINT_MASK,
['\x7F'+1] = CNTRL_MASK,
...continue for second half of 8859-x character set...
};
#define isalpha(c) ((ctype_bits+1)[c] & ALPHA_MASK)
#define isupper(c) ((ctype_bits+1)[c] & UPPER_MASK)
#define islower(c) ((ctype_bits+1)[c] & LOWER_MASK)
#define isalnum(c) ((ctype_bits+1)[c] & ALNUM_MASK)
#define isgraph(c) ((ctype_bits+1)[c] & GRAPH_MASK)
#define isprint(c) ((ctype_bits+1)[c] & PRINT_MASK)
#define iscntrl(c) ((ctype_bits+1)[c] & CNTRL_MASK)
#define isdigit(c) ((ctype_bits+1)[c] & DIGIT_MASK)
#define isblank(c) ((ctype_bits+1)[c] & BLANK_MASK)
#define isspace(c) ((ctype_bits+1)[c] & SPACE_MASK)
#define ispunct(c) ((ctype_bits+1)[c] & PUNCT_MASK)
#define isxdigit(c) ((ctype_bits+1)[c] & XDIGT_MASK)
如前所述,此处的名称实际上位于为用户保留的命名空间中,因此如果您查看 <ctype.h>
header ,您会发现更多神秘名称,它们可能都以一两个下划线开头。
关于C isupper() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2169261/
我正在阅读一本关于 c++ 的书(Ulla Kirch-Prinz 和 Peter Prinz 编写的 C++ 编程完整指南;ISBN:0-7637-1817-3),其中提到了 isupper(),以
我目前正在阅读“The C Programming Language 2nd edition”,我对这个练习不太清楚: Functions like isupper can be implemente
我必须检查字符串的第一个字符是小写还是大写。 当我使用英语名称(如David),但弹出带有重音字母的名称(如Á,É,Í,Ó等)(如Árpád)时,效果很好,然后它认为它是小写字母。 string na
这就是问题所在,我的程序没有将大写字母更改为小写字母。我不明白为什么不。 #include #include using namespace std; int main(){ string
我正在学习 haskell,我正在尝试编写一些简单的函数。在我使用函数 isUpper 之前,一切都运行良好。由于此错误,我无法编译该项目: [1 of 1] Compiling Main
这个问题在这里已经有了答案: C# method group strangeness (2 个答案) 关闭 9 年前。 我刚刚看到以下答案:Is there a better way to crea
我收到指向“in”语句的“无效语法”错误。我的错误是什么? while(notes > 1): note = choice(scale) if note[0].isupper() an
我似乎无法弄清楚为什么我的输出只有一倍。 #include #include int my_isupper(int c); int my_tolower(int c); int main(int ar
我正在尝试使用 lex 和 yacc 进行编译器,但由于某种原因,该代码无法在我的 MAC 中的 VM 机器中运行,因为它说 header 中缺少一些函数。这些函数是 islower() 和 isup
我有一个 std::wstring,我想找出哪个字符在上面大小写,哪些是小写。 std::isupper 和 islower 似乎只处理 ASCII 字符,但我希望能够找出所有字符各种大小写字符 例如
我在官方看到了这个说法Python documentation : str.upper().isupper() might be False 有人可以解释一下吗? 最佳答案 如果字符串是数字或由没有大
我正在尝试编写一个函数,它使用 for 循环和 isupper 方法来仅打印字符串的大写字母。 到目前为止我做了什么: upper_chars = "" def only_upper(s):
我创建了一个简单的程序来检查用户输入的字母是大写还是小写,然后使用std::isupper()和std::islower()函数将小写字母转换为大写字母,并将大写字母转换为小写字母。在运行代码时,我得
我在如何使用 isUpper、isLower 和 isDigit 时遇到了问题。具体来说,我试图获取一个字符串并为字符串中的每个字符返回一个元组列表,其中包含三个 Bool 值,用于表示字符是大写字母
我有一个类似这样的代码片段: char choice; do { cout > choice; if(islower(choice) == 0){ toupper(choice); }
我需要计算用户输入的句子中大写字母的数量。 当我在 Google 上搜索解决方案时,我遇到了命令 sum(1 for c in sentence if c.isupper()))。 我使用了它并且它有
谁能向我解释他们将如何找出字符串单词的大写和小写字母?我需要知道单词是说“fish”、“Fish”、“FISH”还是“fISH”。到目前为止,这是我的代码: #include #include #
这个问题在这里已经有了答案: std::transform() and toupper(), no matching function (3 个回答) 去年关闭。 考虑以下代码: #include
这段代码只输出大写字母的个数。它总是将 numMarks 和 numSpaces 输出为 0。我也尝试过 sentence.c_str() 得到相同的结果。我无法理解发生了什么。 cout int
关于 islower() 和 isupper() 的下面两行在 Mike Banahan 的 C 书的同一段落中给出了 (Link: Section 9.3) : islower(int c) Tru
我是一名优秀的程序员,十分优秀!