代码之家  ›  专栏  ›  技术社区  ›  skylight

在指定位置结构中将一个字符更改为另一个指定字符

  •  0
  • skylight  · 技术社区  · 7 年前

    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', '\0', '\0'
        };
    
        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] != '\0') {
            if (s[j] == 'a')
                putchar ('d');
            if (s[j] == 'b')
                putchar ('z');
            if (s[j] == 'z')
                putchar ('a');
            j++;
        }
        return 0;
    }
    

    但它给我输出dz,只和不返回整个单词时,我放弃了键入。

    2 回复  |  直到 7 年前
        1
  •  0
  •   David C. Rankin    7 年前

    除了另一个答案,而且与之一致的是,你还缺少一些基本要素。

    当你进入 encodeChar ,您使用什么参数来告诉您有多少个元素 table 桌子 检查 table[i].source 针对每个字符确定是否需要替换,对吗?)

    注: C通常使用所有 小写字母 保留所有变量和函数名 大写字母 用于常量和宏。C避免使用 骆驼壳 混合案例 名称——留给C++或java。虽然这是一个风格问题,所以很大程度上取决于你,但它确实说明了你对C的欣赏,就像使用 gets

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

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

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

    使用常量可以避免通过选择多个数组声明来更改其大小。上面有一个方便的地方可以进行更改。

    不要使用 ,它无法防止缓冲区溢出,已从C11中删除。使用 fgets . 全部有效 线路导向型 输入功能(例如。 ,和POSIX getline ) 阅读并包含 尾随 '\n' 它们在缓冲区中填充输入。因此,您需要从输入中修剪尾随的换行符,否则您将 “\n” 挂起存储的任何字符串的末尾,这可能会导致比较等问题。。只需获取长度并检查字符 length - 1 验证它是一个 “\n” ,然后用 nul终止 角色( '\0' 0 ,它们是等效的)

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

    通过使用 --len 现在,新长度保留在 len .

    最后,为了您的 encodechar 函数,您需要知道 桌子 s 表[i]。来源 如果找到匹配项,则您将分配 table[i].code t 然后转到下一个角色。如果未找到,则只需在中指定字符 s t .

    注: 不需要第5个元素 (例如。 '\0' '\0' ),您可以轻松 nul终止 t 没有它,它就不是替代品。

    综合起来,你可以写 编码器字符 类似于以下内容:

    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() is类型 int 因此返回一个值(请参见: C11 Standard §5.1.2.2.1 Program startup (draft n1570) . 另请参见: 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 \0 */
    
        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 */
    }
    

    使用/输出示例

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

    始终使用编译 已启用警告 不要 接受代码,直到它 在没有警告的情况下干净地编译 . 要启用警告,请添加 -Wall -Wextra 给你的 gcc 编译字符串。(添加 -pedantic 以获取更多警告)。对于 VS ( cl.exe 在windoze上),添加 /Wall . 对于 clang 添加 -Weverything . 阅读并理解每个警告。他们将确定任何问题,以及出现问题的确切路线。通过简单地听编译器告诉您的内容,您可以像从大多数教程中学习一样了解编码。

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

        2
  •  0
  •   autistic    7 年前

    如果您能解释一下您在哪里输出任何字符 除了 a , z d 在此代码内:

    void encodeChar(Rule table[5], char *s, char *t)
    {
        int j =0;
    
        while(s[j] != '\0')
        {
            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、 最重要的是,如果我的 受过良好教育 没有它,你就无法安全地学习C。它不是 理论上不可能 但是 这几乎是不可能的 你不会浪费时间 大量的时间 非常不稳定的代码 .

    我推荐K&R2E。它不是 初学者友好型 从某种意义上说,它假设您知道一些其他编程概念,但同样,C不是一个 初学者友好型 从某种意义上说,你不能把脸撞在键盘上就赢了。

    如果你在找什么 初学者友好型 初学者友好型 资源,或任何从 新手

    如果你要用C语言编程,你应该能够阅读。。。来自编译器和 所有这些都需要对代码所需的细节给予同样的关注。

    如果你没有书就想学习任何东西,你很可能不得不忘记。所以 立即停止猜测,立即开始阅读 希望下次我收到你的来信时,这不是什么事 书中解释 .