在C中转换字符?

时间:2011-12-15 08:19:46

标签: c

我的程序的目标是从标准输入接收文本和'数字',并在字母“数字”移位后将文本返回到屏幕(对于第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

这是什么意思?

6 个答案:

答案 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;
  }