除了,并且与对方的回答一致,还有你缺少基本面。
当你进入encodeChar
,你用什么参数来告诉你table
有多少个元素? (你想遍历每个字符table
中的每个元素,检查table[i].source
对每个字符以确定是否需要替换,对吗?)
注:Ç通常使用的变量和函数名都小写同时保留常量和宏都大写。 C避免使用camelCase和MixedCase名称 - 将这些用于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].code
至t
并转至下一个字符。如果找不到,您只需将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
)。对于VS(cl.exe
on windoze),请添加/Wall
。对于clang
,请添加-Weverything
。阅读并理解每个警告。他们会识别出任何问题,以及它们出现的确切路线。您可以尽可能多地了解编码,只需从大多数教程中听取编译器告诉您的内容即可。
看看,让我知道你是否还有其他问题。
你为什么觉得我不看书? – Sebivor
我会告诉你为什么...... 1 /这个问题是如此基本,以至于*读*书的人通常都没有它,2 /这是我从*不读*的人那里看到的那种问题3 /我每天看到这样的问题几十次,4/**而不是一个接一个地问这样的问题,你可以通过阅读一本书节省大量时间** – Sebivor
感谢: )@Sebivor – skylight