将 ASCII 字符转换为字母索引是什么意思,我该怎么做?
what's meant by converting an ASCII character to alphabetical index and how can i do that?
在 Caesar (CS50) 中,它说我需要在其中一个步骤中将 ASCII 字符转换为字母索引。那是什么意思?我看到一个视频说 我“需要找到数字的 ASCII 值与其在字母表中的实际索引之间的关系”,但我还没有真正理解如何实现它*和*到底是什么关系。
- 请详细说明你的回答,因为我是新手。
string plaintext = get_string("plaintext;");
这意味着单个char
变量不过是一个包含ASCII码的整数,例如'A'
为65。算法使用 0 到 25 的间隔可能比 65 到 90 更方便。
通常,如果您知道 char
是大写字母,您可以通过从中减去字母 'A'
来简单地转换为字母索引。天真,因为严格来说,符号 (ASCII) table 中的字母不需要相邻放置。对于初学者级别的程序,应该没问题:
char str[] = "ABC";
for(int i=0; i<3; i++)
printf("%d ", str[i] - 'A'); // prints 0 1 2
而 100% portable 转换器函数可能看起来像这样:
int ascii_to_int (char ch)
{
const char LOOKUP_TABLE [128] =
{
['A'] = 0,
['B'] = 1,
...
};
return LOOKUP_TABLE[ch];
}
这里有一个例子。它是可移植的,因为它不依赖于字符编码。
const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int getIndex(const char *alphabet, int c)
{
int result = -1;
const char *res;
res = strchr(alphabet, c);
if(res)
{
result = res - alphabet;
}
return result;
}
int main(void)
{
char *str = "Hello World!!!";
while(*str)
{
printf("Index of %c is %d\n", *str, getIndex(alphabet, *str));
str++;
}
}
您可能知道也可能不知道 ASCII 字符被编码为 8 位值和字符常量,实际上,在 C 中具有 int
类型。
利用这些知识,您可以像对待普通数字一样对字符进行运算,举个例子:
printf("%d\n", 'a');
这会打印 'a'
的 int
值,即 97
。
现在这个:
printf("%d\n", 'g' - 'a');
这将打印 6
这是 103 - 97
.
的结果
现在你的字符串:
const char* plaintext = "plaintext";
for(size_t i = 0; i < strlen(plaintext); i++){
printf("%c - %d\n",plaintext[i], plaintext[i] - 'a' + 1);
}
结果:
p - 16
l - 12
a - 1
i - 9
n - 14
t - 20
e - 5
x - 24
t - 20
如您所见,打印结果是字母表中字母的索引 1...26
,我在结果中添加了 1
,因为如您所知,在 C 中索引从 [= 开始22=] 你会得到 0...25
.
所以底线是你可以使用这个字符算法来查找字符的索引,这也适用于大写,但你不能混合使用两者。
请注意,还有其他字符编码不允许这种算法,因为字母字符不是按顺序排列的,例如 EBCDIC。
在 Caesar (CS50) 中,它说我需要在其中一个步骤中将 ASCII 字符转换为字母索引。那是什么意思?我看到一个视频说 我“需要找到数字的 ASCII 值与其在字母表中的实际索引之间的关系”,但我还没有真正理解如何实现它*和*到底是什么关系。
- 请详细说明你的回答,因为我是新手。
string plaintext = get_string("plaintext;");
这意味着单个char
变量不过是一个包含ASCII码的整数,例如'A'
为65。算法使用 0 到 25 的间隔可能比 65 到 90 更方便。
通常,如果您知道 char
是大写字母,您可以通过从中减去字母 'A'
来简单地转换为字母索引。天真,因为严格来说,符号 (ASCII) table 中的字母不需要相邻放置。对于初学者级别的程序,应该没问题:
char str[] = "ABC";
for(int i=0; i<3; i++)
printf("%d ", str[i] - 'A'); // prints 0 1 2
而 100% portable 转换器函数可能看起来像这样:
int ascii_to_int (char ch)
{
const char LOOKUP_TABLE [128] =
{
['A'] = 0,
['B'] = 1,
...
};
return LOOKUP_TABLE[ch];
}
这里有一个例子。它是可移植的,因为它不依赖于字符编码。
const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int getIndex(const char *alphabet, int c)
{
int result = -1;
const char *res;
res = strchr(alphabet, c);
if(res)
{
result = res - alphabet;
}
return result;
}
int main(void)
{
char *str = "Hello World!!!";
while(*str)
{
printf("Index of %c is %d\n", *str, getIndex(alphabet, *str));
str++;
}
}
您可能知道也可能不知道 ASCII 字符被编码为 8 位值和字符常量,实际上,在 C 中具有 int
类型。
利用这些知识,您可以像对待普通数字一样对字符进行运算,举个例子:
printf("%d\n", 'a');
这会打印 'a'
的 int
值,即 97
。
现在这个:
printf("%d\n", 'g' - 'a');
这将打印 6
这是 103 - 97
.
现在你的字符串:
const char* plaintext = "plaintext";
for(size_t i = 0; i < strlen(plaintext); i++){
printf("%c - %d\n",plaintext[i], plaintext[i] - 'a' + 1);
}
结果:
p - 16
l - 12
a - 1
i - 9
n - 14
t - 20
e - 5
x - 24
t - 20
如您所见,打印结果是字母表中字母的索引 1...26
,我在结果中添加了 1
,因为如您所知,在 C 中索引从 [= 开始22=] 你会得到 0...25
.
所以底线是你可以使用这个字符算法来查找字符的索引,这也适用于大写,但你不能混合使用两者。
请注意,还有其他字符编码不允许这种算法,因为字母字符不是按顺序排列的,例如 EBCDIC。