如何移动chars w / pointers

时间:2017-07-01 13:20:40

标签: c pointers

我试图在C中编写一个函数来移动char *的每个字母,因此'a'变为'z''b'变为'y' }。在下面的if声明中,我理解(*p - 'a')p指向的字母,但我不确定如何转移字符以实现期望的结果。任何指导将不胜感激。

void encode(char *s1, char *s2) {
    char *p, *q;

    q = s2;
    for (p = s1; p < p + p[STR_LEN]; p++, q++) {
        if (*p >= 'a' && *p <= 'z') {
            *q = (*p - 'a');
        } else
        if (*p >= 'A' && *p <= 'Z') {
            *q = (*p - 'A');
        }
    }
}

修改 感谢您的帮助!看起来最好的算法是* q =&#39; A&#39; +&#39; Z&#39; - (* p),但由于某种原因,它只编码第一个和第二个单词,以此▒作为空格。问题显然是我的其余代码,所以我会开始工作。再次感谢!

EDIT2

我必须添加下面的代码来说明空格字符。再次感谢!

else if (*p == ' ')
            {
                    *q = ' ';
            }

4 个答案:

答案 0 :(得分:1)

问题在于*q = (*p - 'a');

看看发生了什么!想象一下*p是&#39; c。 *q然后变为99-97 = 2,即 ASCII 2 的字符值。相反,它应具有 120 的ASCII值,即x。

因此使用带ASCII值的普通算术。这将导致

*q='a'+'z'-(*p);//97+122-99=120 for *p='c'

同样适用于A-Z范围

*q='A'+'Z'-(*p);

所以代码看起来像这样:

void encode(char *s1, char *s2) {
    char *p, *q;

    q = s2;
    p=s1;
    int i;
    for (i=0; i<STR_LEN; i++) {// I am assuming that STR_LEN is a macro or global value.
        if (*p >= 'a' && *p <= 'z') {
            *q='a'+'z'-(*p);
        } else if (*p >= 'A' && *p <= 'Z') {
            *q='A'+'Z'-(*p);
        }else {
            *q=*p;
        }
        p++;
        q++;
    }
}

答案 1 :(得分:1)

您的公式不正确:

  • 你对字符串结尾的测试是奇怪的,你应该只检查'\0'终结符。
  • 您必须从a中减去角色与z的差异。
  • 你还应该复制非字母的字符。
  • 您应该在目标字符串的末尾设置一个空终结符。

以下是修改后的版本:

void encode(char *s1, char *s2) {
    char *p, *q;

    for (p = s1, q = s2; *p != '\0'; p++, q++) {
        if (*p >= 'a' && *p <= 'z') {
            *q = 'z' - (*p - 'a');
        } else
        if (*p >= 'A' && *p <= 'Z') {
            *q = 'Z' - (*p - 'A');
        } else {
            *q = *p;
        }
    }
    *q = '\0';
}

请注意,此程序假定所有小写和大写字符都是连续的,对于ASCII而言是正确的,但对于EBCDIC则为false。

以下是对所有字符集执行泛型替换的替代版本:

char const source_set[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char const mirror_set[] = "zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";

void encode(const char *src, char *dest) {
    for (; *src; src++, dest++) {
        const char *p = strchr(source_set, *src);
        *dest = p ? mirror_set[p - source_set] : *src;
    }
    *dest = '\0';
}

请注意,参数的顺序与常见做法不一致,根据标准库示例:strcpymemcpy以及许多其他人在源数组之前传递目标。

这是8位字符的另一种解决方案,需要初始化步骤,但会产生非常有效的编码功能:

char const source_set[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char const mirror_set[] = "zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
char encode_array[256];

void encode_initialize(void) {
    for (int i = 0; i < 256; i++) {
        encode_array[i] = (char)i;
    }
    for (int i = 0; source_set[i]; i++) {
        encode_array[(unsigned char)source_set[i]] = mirror_set[i];
    }
}

void encode(const char *src, char *dest) {
    while ((*dest++ = encode_array[(unsigned char)*src++]) != '\0')
        continue;
}

答案 2 :(得分:1)

*q = ('z' - *p) + 'a';

数字0变为数字25,数字25变为数字0。

答案 3 :(得分:0)

请参阅以下代码。它会根据您的需要移动所有字母。 'a'变为'z','A'变为'Z','b'变为'y','B'变为'Y'等......

注意:这里我假设s1是要移位的字母,结果是s2。

void encode(char *s1, char *s2) {
    if ((*s1 >= 'a') && (*s1 <= 'z')) {
        *s2 = 'z' - (*s1 - 'a');
    } else if ((*s1 >= 'A') && (*s2 <= 'Z')) {
        *s2 = 'Z' - (*s1 - 'A');
    }
}