C 编写仅使用循环和条件语句检查升序序列的代码
我被要求用c语言编写一个代码,检查输入的字母顺序,并确定有多少合法顺序。顺序是这样的:我收到多个输入,数字从1-9开始,字母从A-Z开始,后跟“@”,这决定了输入的结束。收到数字后,我应检查以下字母,这意味着如果a收到数字3,我应检查接下来的3个字母,依此类推,这些字母应按字母升序排列。例如,ABC3DEF@ABC-不是合法序列。然而,3DEF是一个合法的序列,所以我总共有一个合法的序列 我尝试了一些东西,但不起作用,输出总是0!注意:我只允许使用循环和条件语句,这意味着没有数组、函数、指针。。。。有没有我想不起来的想法?还是我的想法错了C 编写仅使用循环和条件语句检查升序序列的代码,c,c89,C,C89,我被要求用c语言编写一个代码,检查输入的字母顺序,并确定有多少合法顺序。顺序是这样的:我收到多个输入,数字从1-9开始,字母从A-Z开始,后跟“@”,这决定了输入的结束。收到数字后,我应检查以下字母,这意味着如果a收到数字3,我应检查接下来的3个字母,依此类推,这些字母应按字母升序排列。例如,ABC3DEF@ABC-不是合法序列。然而,3DEF是一个合法的序列,所以我总共有一个合法的序列 我尝试了一些东西,但不起作用,输出总是0!注意:我只允许使用循环和条件语句,这意味着没有数组、函数、指针。。
int i, x, sum = 0;
char cha, c = 0;
while((cha = getchar()) != '@') {
scanf("%d %c", &x, &cha);
cha = c;
if(x >= 1 && x <= 9) {
for(i = 0; i < x; i++) {
if(c == cha - i) {
sum++;
}
c--;
}
}
}
每次测试while循环条件时,都会读取一个字符,如果它不是@,则会丢弃它。这些被丢弃的字符是需要解析的数据的一部分
每次调用scanf时,如果下一个字符是十进制数字或a+或a-,则将该字符和以下所有数字解析为十进制数字,然后读取并最终丢弃下一个字符
您根本不会尝试读取以下任何字符,也不会测试它们是否为字母而不是数字
如果输入中没有@字符,并且在某些情况下,即使有@字符,程序也不会终止。为了解决这个问题,除了测试“@”之外,还应该测试EOF。此外,要正确地执行此操作,必须将getchar的返回值存储为int;char不能表示EOF
基本上,所呈现的代码几乎没有任何效果
像您需要编写的解析器,倾向于显式或隐式地作为状态机编写。你从一个初始状态开始。您读取一些输入字符,并根据当前状态和读取的输入执行适当的操作,通常包括将当前状态更改为其他状态。起泡、冲洗、重复,直到达到一个终端状态,该状态至少应在输入结束时达到。正如评论中指出的,混合使用scanf和getchar充满了陷阱。以代码为例,以解析字符串为目标ABC3DEF@. 您对getchar和scanf的调用说明了这个问题
while((cha = getchar()) != '@') {
scanf("%d %c", &x, &cha);
...
}
当您阅读cha时,测试cha=getchar!='@'对于除“@”之外的每个字符都将为TRUE。因此,对于第一次读取时的序列,cha='A'和BC3DEF@保留在stdin中。然后尝试使用scanf%d%c、&x、&cha;匹配失败是因为“B”不是整数值的有效开始,从stdin中提取字符时,stdin中的“B”将停止未读。x或cha都不是赋值
然后尝试:
cha = c;
if(x >= 1 && x <= 9) {
注:,我使用了int c;你在哪里用过茶
然后,您可以在三个主要条件下处理需要完成的所有其他事项,例如:
while ((c = getchar()) != EOF && c != '\n') {
if (isdigit (c)) { /* if c is digit */
...
}
else if (isalpha(c)) { /* if c is [A-Za-z] */
...
}
else if (c == '@') { /* if c is end character */
...
}
}
在此基础上,您只需定义几个变量,以帮助跟踪您是否处于有效序列中,序列当前是否为合法lgl,作为序列nchr一部分读取的字符数,以及序列开头转换的整数num,以及跟踪上一个上一个字符,例如
char buf[MAXC];
int c, in = 0, lgl = 1, nchr = 0, num = 0, prev = 0;
这样,您就可以一次只读取一个字符,跟踪循环中操作的当前状态
while ((c = getchar()) != EOF && c != '\n') {
if (isdigit (c)) { /* if c is digit */
if (!in) /* if not in seq. set in = 1 */
in = 1;
num *= 10; /* build number from digits */
num += c - '0';
}
else if (isalpha(c)) { /* if c is [A-Za-z] */
if (in) {
if (prev >= c) /* previous char greater or equal? */
lgl = 0; /* not a legal sequence */
prev = c; /* hold previous char in order */
if (nchr < MAXC - 1) /* make sure there is room in buf */
buf[nchr++] = c; /* add char to buf */
}
}
else if (c == '@') { /* if c is end character */
/* if in and legal and at least 1 char and no. char == num */
if (in && lgl && nchr && nchr == num && num < MAXC) {
buf[num] = 0; /* nul-terminate buf */
printf ("legal: %2d - %s\n", num, buf); /* print result */
}
lgl = 1; /* reset all values */
in = nchr = num = prev = 0;
}
}
注意:您可以根据需要调整MAXC以更改字符数
现在,您可以练习代码,并确保它能够满足您的转换需求。您可以调整输出以满足您的需求。虽然在将逻辑整合起来时已经非常小心,但任何可能需要处理的角落案例都留给您处理
示例使用/输出
或
或者如果没有最后的“@”,即使是其他合法序列也将被丢弃
$ echo "ABC3DEF@11abcdefghijk@3AbC@4AZaz" | ./bin/sequences
legal: 3 - DEF
legal: 11 - abcdefghijk
注意:如果您确实希望接受最终的合法序列,即使在EOF之前没有结束'@',您只需在while循环终止后添加一个附加条件即可,例如
/* handle final sequence before EOF */
if (in && lgl && nchr && nchr == num && num < MAXC) {
buf[num] = 0; /* nul-terminate */
printf ("legal: %2d - %s\n", num, buf); /* print result */
}
有了这个变化,上面的最后一个示例将与其他示例的输出相匹配。缩进样式中的模式是什么;立即对从scanf获得的值进行过度加载。并且从输出总是0-在哪里?张贴的代码没有输出。@Cacahuetferito我相信它的灵感来自毕加索的立体主义。哈啰!请发布显示问题的。这还应该显示您正在使用的include文件、输入、预期输出以及问题中的文本形式的实际输出。还要注意,问题描述令人困惑。你想要回答的具体C代码问题是什么?@Christiangibons抱歉我破坏了它;非常感谢你的解释
. 你看,我对编码是新手,多亏了你,我现在明白了什么是getchar。但是,有没有其他方法可以从输入中识别数字来替换ifisdigitc?如果我的数字输入是为1-9之间的数字指定的,并且我将识别数字的条件替换为:**ifc-'0'>=1&&c-'0',如果isdigit c&&c>'0'num=c-'0',您会做得更好;。使用isdigit的支票将告诉您它是一个数字,而c>'0'将告诉您它是1-9。
$ echo "ABC3DEF@11abcdefghijk@4AZaz@3AbC@" | ./bin/sequences
legal: 3 - DEF
legal: 11 - abcdefghijk
legal: 4 - AZaz
$ echo "ABC3DEF@11abcdefghijk@3AbC@4AZaz@" | ./bin/sequences
legal: 3 - DEF
legal: 11 - abcdefghijk
legal: 4 - AZaz
$ echo "ABC3DEF@11abcdefghijk@3AbC@4AZaz" | ./bin/sequences
legal: 3 - DEF
legal: 11 - abcdefghijk
/* handle final sequence before EOF */
if (in && lgl && nchr && nchr == num && num < MAXC) {
buf[num] = 0; /* nul-terminate */
printf ("legal: %2d - %s\n", num, buf); /* print result */
}