2017-09-27 63 views
0

我需要更改指定的字符,例如:字符串中的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', '\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,并且不会返回整个单词时,我输入被放弃。

+0

你为什么觉得我不看书? – Sebivor

+0

我会告诉你为什么...... 1 /这个问题是如此基本,以至于*读*书的人通常都没有它,2 /这是我从*不读*的人那里看到的那种问题3 /我每天看到这样的问题几十次,4/**而不是一个接一个地问这样的问题,你可以通过阅读一本书节省大量时间** – Sebivor

+0

感谢: )@Sebivor – skylight

回答

0

除了,并且与对方的回答一致,还有你缺少基本面。

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

注:Ç通常使用的变量和函数名都小写同时保留常量和宏都大写。 C避免使用camelCaseMixedCase名称 - 将这些用于C++或java。虽然这是一个风格问题,所以它在很大程度上取决于你,但它确实说了很多关于你的赞赏,C,就像使用gets确实....

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

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

如果你有多个常数声明,使用enum是声明全局常量有序推进。

使用常量可以防止必须选择多个数组声明来更改它们的大小。有一个方便的地方可以进行更改。

不要使用gets,它无法抵抗缓冲区溢出并已从C11中删除。使用fgets。所有有效的面向行的输入函数(例如fgets和POSIX getline读取并包括尾随'\n'在它们填充输入的缓冲区中。因此,您需要从输入中修剪尾随的换行符,否则将会有一个'\n'悬挂在您存储的任何可能导致比较问题的字符串末尾。只需获取长度并检查字符length - 1以验证它是'\n'

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

注:现在使用--len公顷,然后只需用NUL终止字符('\0'0,它们是相同的)

这是很简单的,如将其覆盖已保存的新长度为len

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

注:没有必要为table第五元素(例如'\0''\0'),你可以很容易地NUL,终止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,因此返回一个值(参见: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编译字符串中。 (为0123几个额外的警告添加-pedantic)。对于VScl.exe on windoze),请添加/Wall。对于clang,请添加-Weverything。阅读并理解每个警告。他们会识别出任何问题,以及它们出现的确切路线。您可以尽可能多地了解编码,只需从大多数教程中听取编译器告诉您的内容即可。

看看,让我知道你是否还有其他问题。

+0

这显然帮了我很大的忙。澄清我的疑惑并提供充分的解释。我是C新手,我希望有一天掌握了C语言,我将能够将我的知识分享给新程序员,因为我了解他们的情况。先生,谢谢你的时间! @david – skylight

+0

你会的。学习C是一次旅程,而不是一场比赛,享受这次旅程。 –

0

如果你会这么好心来解释,你输出a,这段代码中zd其他任何字符:

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.S.最重要的是,如果我的颇受教育的猜测是正确的,你需要一本书!你无法安全地学习C没有一个。这不是理论上是不可能,但实际上是不可能,你马上就不会浪费时间堆写真正不稳定的代码

我推荐K & R2E。这不是在某种意义上初学者友好,它假设你知道一些其他的编程概念,但话又说回来,C是不是在说你不能只是混搭你的脸对着键盘,赢得感初学者友好语言。

如果您正在寻找初学者友好型,请选择其他语言。 C没有尚未有任何初学者友好资源,或从初学者水平开始,到我所知,任何有信誉的老师。

如果您打算使用C语言进行编程,您可以阅读......编译器和valgrind中的书籍,手册和错误消息,都需要注意细节,以便您的代码需要。

任何你没有书就可以学会的东西,你很可能不得不忘记。所以立即停止猜测,立即开始阅读,并希望下次我收到你的消息时,基本不是所解释的东西。

+0

将OP引导至以下链接也许会有所帮助[**如何调试小程序**](https://ericlippert.com/2014/03/05/how-to-debug-small-programs /)和** note **与鸭子交谈......':))' –

相关问题