将指定位置结构中的一个Char更改为另一个指定的Char

Changing a Char to another specified Char in a specified position structure

我需要更改字符串中的指定字符,例如:a->z、d->b。例如:输入被放弃;输出是 zbznboneb。这是我的代码。

typedef struct {
    char source;
    char code;
} Rule;

void encodeChar (Rule table[5], char *s, char *t);

int main ()
{
    char s[80], t[80];
    Rule table[5] = { 'a', 'd', 'b', 'z', 'z', 'a', 'd', 'b', '[=10=]', '[=10=]'
    };

    printf ("Source string: \n");
    gets (s);
    encodeChar (table, s, t);
    printf ("Encoded string: %s\n", t);
    return 0;
}

void encodeChar (Rule table[5], char *s, char *t)
{
    int j = 0;

    while (s[j] != '[=10=]') {
        if (s[j] == 'a')
            putchar ('d');
        if (s[j] == 'b')
            putchar ('z');
        if (s[j] == 'z')
            putchar ('a');
        j++;
    }
    return 0;
}

但它只给我输出 dz 而不是 return 整个单词,当我键入 abandoned 时。

如果你能解释一下你在哪里输出任何字符 除了 azd此代码:

void encodeChar(Rule table[5], char *s, char *t)
{
    int j =0;

    while(s[j] != '[=10=]')
    {
        if (s[j] == 'a')
            putchar('d');
        if (s[j] == 'b')
            putchar('z');
        if (s[j]=='z')
            putchar('a');
        j++;
    }
    return 0;
}

请告诉我你 putchar 除了 'a''d' 或“z”之外的任何地方,你会得到一些 强烈提示 回答你的问题。

P.S。最重要的是,如果我 相当有教养的 猜测是正确的,那么您需要一本书! 没有一本书您就无法安全地学习 C。这并非理论上不可能,但实际上不太可能你在不浪费大量时间[=49]的情况下做对=] 编写 非常不稳定的代码.

我推荐K&R2E。它不是初学者友好的,因为它假定您了解一些其他编程概念,但话又说回来,C 不是 初学者友好的 语言感觉你不能只是把你的脸砸在键盘上然后赢。

如果您正在寻找初学者友好的内容,请选择其他语言。据我所知,C 还没有任何 初学者友好的 资源,或任何从 初学者 水平开始的知名教师。

如果你打算用 C 编程,你应该能够阅读...书籍、手册和来自编译器的错误消息,valgrind 都需要同样关注您的代码所需的细节。

任何你在没有书的情况下设法学会的东西,你很可能不得不忘掉。所以立即停止猜测,立即开始阅读,希望下次我收到您的来信时,这与基本解释的内容无关书.

除了并同意另一个答案之外,您还缺少一些基本知识。

当您进入 encodeChar 时,您使用什么参数来告诉您 table 有多少个元素? (您确实想遍历 table 中的每个元素,检查每个字符 table[i].source 以确定是否需要替换,对吧?)

注意: C 通常使用所有 小写字母 作为变量和函数名称,同时保留所有 大写字母 常量和宏。 C 避免使用 camelCaseMixedCase 名称——将它们留给 C++ 或 java。虽然这是一个风格问题,所以它在很大程度上取决于您,但它确实说明了您对 C 的欣赏,就像使用 gets 一样....

不要在代码中使用幻数。如果您需要一个常量(例如 80),请在代码顶部声明一个,例如

#define MAXC 80   /* maximum characters for input buffer */

如果要声明多个常量,使用 enum 是一种有序的声明全局常量的方法。

使用常量可以避免必须通过多个数组声明来更改它们的大小。顶部有一个方便的地方可以进行更改。

不要使用gets,它对缓冲区溢出无能为力,已从C11中删除。使用 fgets。所有有效的 line-oriented 输入函数(例如 fgets 和 POSIX getlineread and include他们用输入填充的缓冲区中的尾随 '\n'。因此,您需要 trim 来自输入的尾随换行符,否则您将 '\n' 悬挂在您存储的任何字符串的末尾,这可能会导致比较等问题。只需获取长度并检查字符 length - 1 来验证它是一个 '\n',然后用 nul-terminating 字符覆盖它('[=30=]'0,它们是等价的)

很简单,例如:

len = strlen (s);                  /* get length of s   */
if (len && s[len - 1] == '\n')     /* check for \n      */
    s[--len] = 0;                  /* overwrite with [=11=] */

注意: 通过使用 --len 您现在可以在 len.

中保留新的长度

最后,对于 encodechar 函数,您需要知道 table 中有多少个元素。对于 s 中的每个字符,如果找到匹配项,您会将其与每个 table[i].source 进行比较,然后将 table[i].code 分配给 t 并转到下一个字符。如果找不到,您只需将 s 中的字符分配给 t.

注意:不需要table的第5个元素(例如'[=30=]''[=30=]'),可以很容易的nul-terminate t 没有它——它不是替代品。

将它们放在一起,您可以写成 encodechar 类似于以下内容:

void encodechar (rule *table, size_t sz, char *s, char *t)
{
    size_t i;

    while (*s) {                            /* for each character */
        int replaced = 0;                   /* replaced flag */
        for (i = 0; i < sz; i++)            /* for each element of table */
            if (*s == table[i].source) {    /* is char == table[i].source */
                *t = table[i].code;         /* replace it */
                replaced = 1;               /* set replaced flag */
                break;                      /* get next character */
            }
        if (!replaced)                      /* if not replaced */
            *t = *s;                        /* copy from s to t */
        s++, t++;                           /* increment s and t */
    }
    *t = 0;                                 /* nul-terminate t */
}

总而言之,注意 main()int 类型,因此 returns 是一个值(参见:C11 Standard §5.1.2.2.1 Program startup (draft n1570). See also: See What should main() return in C and C++?),您可以执行类似以下操作:

#include <stdio.h>
#include <string.h>

#define MAXC 80   /* maximum characters for input buffer */

typedef struct {
    char source;
    char code;
} rule;

void encodechar (rule *table, size_t sz, char *s, char *t);

int main (void) {

    char s[MAXC] = "", t[MAXC] = "";
    rule table[] = { {'a', 'd'}, {'b', 'z'}, {'z', 'a'}, {'d', 'b'} };
    size_t len = 0, n = sizeof table/sizeof *table;

    printf ("Source string : ");
    if (!fgets (s, MAXC, stdin)) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    len = strlen (s);                  /* get length of s   */
    if (len && s[len - 1] == '\n')     /* check for \n      */
        s[--len] = 0;                  /* overwrite with [=13=] */

    encodechar (table, n, s, t);

    printf ("Encoded string: %s\n", t);

    return 0;
}

void encodechar (rule *table, size_t sz, char *s, char *t)
{
    size_t i;

    while (*s) {                            /* for each character */
        int replaced = 0;                   /* replaced flag */
        for (i = 0; i < sz; i++)            /* for each element of table */
            if (*s == table[i].source) {    /* is char == table[i].source */
                *t = table[i].code;         /* replace it */
                replaced = 1;               /* set replaced flag */
                break;                      /* get next character */
            }
        if (!replaced)                      /* if not replaced */
            *t = *s;                        /* copy from s to t */
        s++, t++;                           /* increment s and t */
    }
    *t = 0;                                 /* nul-terminate t */
}

示例Use/Output

$ ./bin/encode
Source string : abcdefghijklmnopqrstuvwxyz
Encoded string: dzcbefghijklmnopqrstuvwxya

始终在启用警告的情况下进行编译,并且不要接受代码,直到它在没有警告的情况下干净地编译.要启用警告,请将 -Wall -Wextra 添加到 gcc 编译字符串。 (添加 -pedantic 以获得几个额外的警告)。对于 VS(windoze 上的 cl.exe),添加 /Wall。对于 clang,添加 -Weverything。阅读并理解每个警告。他们将确定任何问题,以及问题发生的确切路线。与大多数教程一样,您只需聆听编译器告诉您的内容,就可以学到尽可能多的编码知识。

检查一下,如果您还有其他问题,请告诉我。