C-对字符串执行数学运算
我对C中字符的数学运算感到困惑。这是为了实现一个基本的密码。我正在使用命令行参数argv中存储的字符串C-对字符串执行数学运算,c,C,我对C中字符的数学运算感到困惑。这是为了实现一个基本的密码。我正在使用命令行参数argv中存储的字符串 for (int i = 0, n = strlen(p), m = strlen(argv[1]); i < n; i++) { if ((p[i] >= 'A' && p[i] <= 'Z') || (p[i] >= 'a' && p[i] <= 'z')) { if (argv[1][i % m
for (int i = 0, n = strlen(p), m = strlen(argv[1]); i < n; i++)
{
if ((p[i] >= 'A' && p[i] <= 'Z') || (p[i] >= 'a' && p[i] <= 'z'))
{
if (argv[1][i % m] >= 'A' && argv[1][i % m] <= 'Z')
{
printf("%c", ((p[i] - 'A') + ((argv[1][i % m]) - 'A')) % 26);
}
else if (argv[1][i % m] >= 'a' && argv[1][i % m] <= 'z')
{
printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
}
}
else
{
printf("%c", p[i]);
}
然而,我不知道这是为什么。在我看来,我试图做的与教授给出的一个例子没有什么不同:
string s = get_string();
if (s != NULL)
{
for (int i = 0, n = strlen(s); i < n; i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
printf("%c", s[i] - ('a' - 'A'));
}
else
{
printf("%c", s[i]);
}
}
非常感谢您的指导 您是对的,您可以简化代码 在C语言中,像
'a'
这样的东西是int
类型。(与流行的观点相反,它们不是字符
类型,只是C标准保证它们可以被分配到字符
类型,而不会有溢出的危险。)单引号表示法用于避免C不要求特定字符编码的事实。也就是说,您不应该关心数字'a'
等代表什么。如果你真的在意,那么严格来说你的代码是不可移植的C
因此,是的,你的表达形式是
(a-b)-(c-b)
简化为a-c
你是正确的,你可以简化你的代码
printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
在C语言中,像'a'
这样的东西是int
类型。(与流行的观点相反,它们不是字符
类型,只是C标准保证它们可以被分配到字符
类型,而不会有溢出的危险。)单引号表示法用于避免C不要求特定字符编码的事实。也就是说,您不应该关心数字'a'
等代表什么。如果你真的在意,那么严格来说你的代码是不可移植的C
因此,是的,您的形式(a-b)-(c-b)
的表达式简化为a-c
printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
从芭丝谢芭那里偷来的:
是的,你的(a-b)-(c-b)形式的表达式简化为a-c
那么,(a-b)+(c-b)也会得到a+c-2*b
因此,你首先:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26);
// ^ yet left...
下一点是%26-它将计算0到26之间的值-这些都是您可能不想看到的控制字符
请注意,“a”的数值为97,“a”的数值为65(至少在ASCII中…)。因此,您将有兴趣在结果中重新添加此值:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26 + 'a');
// ^ (or 'A' in the upper case case)
从芭丝谢芭那里偷来的:
是的,你的(a-b)-(c-b)形式的表达式简化为a-c
那么,(a-b)+(c-b)也会得到a+c-2*b
因此,你首先:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26);
// ^ yet left...
下一点是%26-它将计算0到26之间的值-这些都是您可能不想看到的控制字符
请注意,“a”的数值为97,“a”的数值为65(至少在ASCII中…)。因此,您将有兴趣在结果中重新添加此值:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26 + 'a');
// ^ (or 'A' in the upper case case)
那么,你的问题到底是什么?角色是-惊喜你可以用来做常规数学运算的数字。请参阅本页查看你的索引:@dan04对不起,我意识到我没有说清楚。我的代码不打印行
printf(“%c”,((p[i]-'a')+((argv[1][i%m])-'a'))%26)代码>但如果该行仅为printf(“%c”,p[i]+argv[1][i%m]),则为我不知道这是为什么。那么,你的问题到底是什么?角色是-惊喜你可以用来做常规数学运算的数字。请参阅本页查看你的索引:@dan04对不起,我意识到我没有说清楚。我的代码不打印行printf(“%c”,((p[i]-'a')+((argv[1][i%m])-'a'))%26)代码>但如果该行仅为printf(“%c”,p[i]+argv[1][i%m]),则为我不知道为什么。字符是int
s?!天哪,这就是为什么strchr
的第二个参数是整数!现在,如果我们可以在任何地方使用int*
,为什么我们需要char
,尤其是char*
来表示字符串呢?@ForceBru请注意,字符文本的类型是int(即,当您编写'a','b','7',…)!(顺便说一下:C++中的不同…)如果你写的是代码> char c;c是char类型,占一个字节(而在大多数现代系统中是int的4个字节)。@ForceBru:如果int
是1的16位补码,则您可能无法这样做。我倾向于将数据填充到本质上可以归结为无符号字符
数组中。@ForceBru一个可以(假设是4字节整数,然后使用无符号变量),但这会将绝大多数文本文档放大四倍,因为大多数文档只使用ASCII。在大多数其他语言中,只有少数字符需要用两个字节编码,例如。G德语、西班牙语(以及其他语言)。@ForceBru:虽然存储可能很便宜,但RAM和网络带宽并没有那么便宜。此外,还有一个问题,即与期望文本字符串由8位代码单元组成的API和协议的向后兼容性。因此,UTF-8仍然是比UTF-32更流行的编码。字符是int
s?!天哪,这就是为什么strchr
的第二个参数是整数!现在,如果我们可以在任何地方使用int*
,为什么我们需要char
,尤其是char*
来表示字符串呢?@ForceBru请注意,字符文本的类型是int(即,当您编写'a','b','7',…)!(顺便说一下:C++中的不同…)如果你写的是代码> char c;c是char类型,占一个字节(而在大多数现代系统中是int的4个字节)。@ForceBru:如果int
是1的16位补码,则您可能无法这样做。我倾向于将数据填充到本质上可以归结为无符号字符
数组中。@ForceBru一个可以(假设是4字节整数,然后使用无符号变量),但这会将绝大多数文本文档放大四倍,因为大多数文档只使用ASCII。在大多数其他语言中,只有少数字符需要用两个字节编码,例如。G德语、西班牙语?