我的程序的目标是从标准输入接收文本和'数字',并在字母“数字”移位后将文本返回到屏幕(对于第3班,'a'变为'd' ','e'变为'g')。它应该只移动小写字母,并且应该是循环的(3的移位中的字母'y'应该再次成为'a'。
但是,我有一些错误。如果我将't'移动11次,它将变为'e',但如果我将't'移动12次,我会得到空格(“”)。为什么?这是我的代码: 3 int main(int argc, char *argv[]) {
4 if (argc != 2) {
5 printf ("Wrong input\n");
6 return 1;
7 }
8 int shift = atoi (argv[1]);
9 int c;
10 while ((c = getchar()) != EOF) {
11 if (c >= 'a' && c <= 'z') {
12 char newch = c + shift;
13 if (newch > 'z') {
14 newch = 'a' + (newch - 'z' - 1);
15 }
16 if (newch < 'a') {
17 newch = 'z' - ('a' - newch - 1);
18 }
19 putchar (newch);
20 }
21 else
22 putchar(c);
23 }
24 return 0;
25 }
此外,在编译时我会收到这些警告:
shift_chars.c: In function `main':
shift_chars.c:8: warning: implicit declaration of function `atoi'
shift_chars.c:8: warning: ISO C90 forbids mixed declarations and code
这是什么意思?
答案 0 :(得分:2)
第一个警告表示您未包含<stdlib.h>
,这是声明atoi()
的位置。
第二个警告意味着您在获得某些可执行代码后声明了变量(shift
等)。 C ++允许这样做; C99允许; ISO C 90(ANSI C 89)不允许这样做。在较旧的C中,必须在任何可执行语句之前定义块中的所有变量。
另外,如果你正在转移3并将'y'翻译为'a'你有一个错误 - 它应该是'b'('z','a','b')。
您的一个问题是“z”的代码是122,如果您的字符(char
类型)已签名,则添加11到122会将您包装为负值;如果char
未签名,则不会出现此问题。在计算新字符值时,您最好使用int
代替char
。
如果计算出来,您可能会发现管理起来更容易:
int newch = ((c - 'a') + shift) % 26 + 'a';
c - 'a'
为您提供字母表索引:a = 0,b = 1,... z = 25.添加班次;取模26的结果再次将字符偏移到字母表中;然后将结果添加到'a'
以获取正确的字母。由于c - 'a'
生成一个整数(因为所有char
值都会提升为int
),因此可以避免char
中的任何溢出。
确实,你可以完全避免newch
并简单地计算:
a = (c - 'a' + shift) % 26 + 'a';
然后,您可以在第19行省略putchar()
,然后删除else
,让putchar(c);
输出已转换和未转换的字符。
答案 1 :(得分:2)
我会用这种方式改变角色:
if(c >= 'a' && c <= 'z') {
newchar = (c - 'a' + shift) % 26 + 'a';
}
至于警告 - 人们完美地解释了它们。
答案 2 :(得分:1)
如果查看ascii表,'t'的值为116.您的平台上可能会签署一个char。
因此,您得到116 + 12 = 128,但是这将使用带符号的8位值表示,因此该值将为-128。然后你最终计算newch = 'z' - ('a' - newch - 1);
如果你使用int newch = c + shift;
,你将不会遇到这个问题(直到加法包裹过2147483648)。
shift_chars.c:8: warning: implicit declaration of function 'atoi'
表示编译器没有看到atoi()函数的声明。您应#include <stdlib.h>
使用atoi
答案 3 :(得分:1)
而不是第12到第18行,只需执行
char newch = (c - 'a' + shift) % 26 + 'a';
答案 4 :(得分:0)
尝试改变
char newch = c + shift;
到
int newch = c + shift;
或unsigned char
答案 5 :(得分:0)
我的回答包括解释和解决方案:
你的newch有一个char
数据类型。大多数机器将char
解释为1个字节。
这意味着newch
变量的最大十进制值为:
11111111(二进制)== 128十进制。那是0-127。
现在,在你的代码中,当你按下't'时,getchar将其作为十进制的116。如果你用12(你的班次)添加它,那么结果将是116 + 12 = 128。从0-127范围溢出128个。
解决方案?使您的newch数据类型能够接受更大的范围,例如:
unsigned char newch = c + shift;
或
int newch = c + shift;
这是完整的代码:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf ("Wrong input\n");
return 1;
}
int shift = atoi (argv[1]);
int c;
while ((c = getchar()) != EOF) {
if (c >= 'a' && c <= 'z') {
unsigned char newch = c + shift;
if (newch > 'z') {
newch = 'a' + (newch - 'z' - 1);
}
if (newch < 'a') {
newch = 'z' - ('a' - newch - 1);
}
putchar (newch);
}
else
putchar(c);
}
return 0;
}