将每个字母移动多个位置后,如何按字母顺序环绕 z 到 a 和 Z 到 A?
How to wrap around alphabetically z to a and Z to A after shifting each letter by a number of places?
我正在编写一个代码,其中我将每个字母移动一个位置,因此 (a) 变为 (b),(b) 变为 (c),依此类推。到目前为止,我设法做到了这一点,但我遇到了将大写字母 (Z) 环绕到 (A) 的问题。我似乎无法理解如何做到这一点。
任何帮助,将不胜感激。
非常感谢。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int main(void)
{
//prompt the user to type in a text.
string p = get_string("plaintext: ");
//create a variable to refer to the length of the string.
int n = strlen(p);
for (int i = 0; i < n; i++)
{
//check if all chars (i) in the string (p) are alphabetical then increment i by 1.
if (isalpha(p[i]))
p[i]++;
{
//check if i has gone beyond the letter (z) and (Z).
if ((p[i] > 'z') && (p[i] > 'Z'))
{
//if so then subtract 26 letter after z or Z to get back to a or A.
p[i] = p[i] - 26;
}
}
printf("%c", p[i]);
}
printf("\n");
}
您需要将 increments/checks 分成大写和小写块,因为尽管字符 a ... z
和 A ... Z
最有可能按顺序排列,它们将是不同个序列。
循环中的这些内容:
for (int i = 0; i < n; i++) {
//check if all chars (i) in the string (p) are alphabetical then increment i by 1.
if (islower(p[i])) { // Lowercase letter check ...
p[i]++;
//check if i has gone beyond the letter (z).
if (p[i] > 'z') {
//if so then subtract 26 letter after z to get back to a.
p[i] = p[i] - 26;
}
}
else if (isupper(p[i])) { // Uppercase letter check ...
p[i]++;
//check if i has gone beyond the letter (Z).
if (p[i] > 'Z') {
//if so then subtract 26 letter after Z to get back to A.
p[i] = p[i] - 26;
}
}
printf("%c", p[i]);
}
(此外,我假设在您的代码中,{
after p[i]++;
是错字 - 否则,您检查每个字符,即使它不是字母。你的缩进表明这不是你想要的。)
另一种更接近初始程序的方法就是替换
if ((p[i] > 'z') && (p[i] > 'Z'))
来自
if ((p[i] == 'z'+1) || (p[i] == 'Z'+1))
避免重复几乎所有代码,因为在另一个答案中就是这种情况
而且我认为替换
更具可读性
p[i] = p[i] - 26;
来自
p[i] -= 'z' - 'a' + 1;
编译器用它的值替换 'z' - 'a' + 1
,表达式自己解释目标
最后,我认为这样做更清楚
if (isalpha(p[i]))
{
if ((p[i] == 'z') || (p[i] == 'Z'))
p[i] -= 'z' - 'a';
else
p[i] += 1;
}
并且白白删除一个增量
或者只有一行:
if (isalpha(p[i]))
p[i] += ((p[i] == 'z') || (p[i] == 'Z')) ? 'a' - 'z' : 1;
但这可能不太可读
其中
printf("%c", p[i]);
价格昂贵,可以用
代替
putchar(p[i]);
我正在编写一个代码,其中我将每个字母移动一个位置,因此 (a) 变为 (b),(b) 变为 (c),依此类推。到目前为止,我设法做到了这一点,但我遇到了将大写字母 (Z) 环绕到 (A) 的问题。我似乎无法理解如何做到这一点。 任何帮助,将不胜感激。 非常感谢。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int main(void)
{
//prompt the user to type in a text.
string p = get_string("plaintext: ");
//create a variable to refer to the length of the string.
int n = strlen(p);
for (int i = 0; i < n; i++)
{
//check if all chars (i) in the string (p) are alphabetical then increment i by 1.
if (isalpha(p[i]))
p[i]++;
{
//check if i has gone beyond the letter (z) and (Z).
if ((p[i] > 'z') && (p[i] > 'Z'))
{
//if so then subtract 26 letter after z or Z to get back to a or A.
p[i] = p[i] - 26;
}
}
printf("%c", p[i]);
}
printf("\n");
}
您需要将 increments/checks 分成大写和小写块,因为尽管字符 a ... z
和 A ... Z
最有可能按顺序排列,它们将是不同个序列。
循环中的这些内容:
for (int i = 0; i < n; i++) {
//check if all chars (i) in the string (p) are alphabetical then increment i by 1.
if (islower(p[i])) { // Lowercase letter check ...
p[i]++;
//check if i has gone beyond the letter (z).
if (p[i] > 'z') {
//if so then subtract 26 letter after z to get back to a.
p[i] = p[i] - 26;
}
}
else if (isupper(p[i])) { // Uppercase letter check ...
p[i]++;
//check if i has gone beyond the letter (Z).
if (p[i] > 'Z') {
//if so then subtract 26 letter after Z to get back to A.
p[i] = p[i] - 26;
}
}
printf("%c", p[i]);
}
(此外,我假设在您的代码中,{
after p[i]++;
是错字 - 否则,您检查每个字符,即使它不是字母。你的缩进表明这不是你想要的。)
另一种更接近初始程序的方法就是替换
if ((p[i] > 'z') && (p[i] > 'Z'))
来自
if ((p[i] == 'z'+1) || (p[i] == 'Z'+1))
避免重复几乎所有代码,因为在另一个答案中就是这种情况
而且我认为替换
更具可读性p[i] = p[i] - 26;
来自
p[i] -= 'z' - 'a' + 1;
编译器用它的值替换 'z' - 'a' + 1
,表达式自己解释目标
最后,我认为这样做更清楚
if (isalpha(p[i]))
{
if ((p[i] == 'z') || (p[i] == 'Z'))
p[i] -= 'z' - 'a';
else
p[i] += 1;
}
并且白白删除一个增量
或者只有一行:
if (isalpha(p[i]))
p[i] += ((p[i] == 'z') || (p[i] == 'Z')) ? 'a' - 'z' : 1;
但这可能不太可读
其中
printf("%c", p[i]);
价格昂贵,可以用
代替putchar(p[i]);