你让自己有点困难。一旦你有了长度,你可以简单地循环多次,从结尾输出字符到开头,然后输出换行符。只需将所有内容都包含在一个循环中,以不断获取输入并检查您的 'd'、"Done" 或 "done" 以打破循环。
(注意:,您可以简单地测试len == 1 & *userText == 'd' 以处理'd' 情况下的退出,而无需调用strcmp() -- 由您决定)
在查看解决方案之前,您应该避免在代码中使用 Magic-Numbers(例如 50)。而是:
...
#define MAXC 50 /* if you need a constant, #define one (or more) */
int main(void) {
char userText[MAXC];
...
if (!fgets (userText, MAXC, stdin)) /* validate EVERY user-input */
return 1;
这样,如果您需要更改字符串的长度,您可以在一个方便的位置调整长度,而无需选择所有函数调用或循环限制来进行更改。
验证每个输入
无论您使用什么输入功能,您都无法正确使用它,除非您检查返回以确定输入是成功还是失败。您在这里使用fgets()(对您有好处!),但您仍然需要检查退货。 fgets() 将在成功时返回指向已填充缓冲区的指针,或在 EOF 或流错误时返回 NULL。因此,您只需确保返回不是NULL 即可验证字符是否保存在userText 中,例如
if (!fgets (userText, MAXC, stdin)) /* validate EVERY user-input */
return 1;
您在第一次迭代中使用len-1 调用未定义行为:
int len;
...
userText[len-1] = '\0';
在第一次迭代中,len 未初始化,并且任何尝试使用具有自动存储持续时间的变量的值而其值不确定会导致未定义的行为。具体来说:
C11 Standard - 6.7.9 Initialization(p10) "如果一个具有自动存储时长的对象没有被显式初始化,它的值是不确定的。" and C11 Standard - J.2 Undefined Behavior"一个具有自动存储时长的对象的值在不确定时使用(6.2.4、6.7.9、6.8)。"
fgets() 将'\n' 包含在填充的缓冲区中
当您尝试使用"d"、"Done" 和"done" 中的strcmp() 时,您将永远无法匹配"d"、"Done" 和"done",因为缓冲区中实际包含的是@ 987654349@、"Done\n" 和 "done\n"。删除'\n' 的一种简单而可靠的方法是使用strcspn(),例如
userText[strcspn (userText, "\n")] = 0; /* trim \n */
你可以通过简单地保存strcspn()的返回来获得没有'\n'的行的长度,例如
size_t len = 0;
...
userText[(len = strcspn (userText, "\n"))] = 0; /* trim \n, save len */
现在您的 strcmp() 支票将匹配。
要反向输出用户输入,只需循环len 次,输出从最后一个字符开始到第一个字符。 while 循环提供了一种简单的迭代方式,例如
while (len--) /* loop len times */
putchar (userText[len]); /* output char (end-to-start) */
putchar ('\n'); /* tidy up with newline */
(注意: 不需要printf ("%c", ... 单个字符,这就是putchar() 或fputc() 的用途。一个好的编译器通常会为您进行优化,但是最好展示对输出如何发生的理解)
把它放在一起并为用户输入提供可选的"user str: " 提示,并为输出提供可选的"reversed: " 前缀(比让你的用户看着闪烁的光标想知道你的程序是否挂起更好),你可以这样做:
#include <stdio.h>
#include <string.h>
#define MAXC 50 /* if you need a constant, #define one (or more) */
int main(void) {
char userText[MAXC];
size_t len = 0;
for (;;) { /* loop continually */
fputs ("\nuser str: ", stdout); /* prompt for input (optional) */
if (!fgets (userText, MAXC, stdin)) /* validate EVERY user-input */
return 1;
userText[(len = strcspn (userText, "\n"))] = 0; /* trim \n, save len */
if ((len == 1 && *userText == 'd') || /* check for 'd' alone */
strcmp(userText, "Done") == 0 || /* check for "Done" */
strcmp(userText, "done") == 0) { /* check for "done" */
return 0;
}
fputs ("reversed: ", stdout); /* prefix for output (optional) */
while (len--) /* loop len times */
putchar (userText[len]); /* output char (end-to-start) */
putchar ('\n'); /* tidy up with newline */
}
return 0;
}
(注意: return 0; 是 C99 转发的默认值,但由于您指定了 C89,所以它是必需的)
使用/输出示例
$ ./bin/outputrev
user str: Hello there
reversed: ereht olleH
user str: Hey
reversed: yeH
user str: done
或者:
$ ./bin/outputrev
user str: My
reversed: yM
user str: dog
reversed: god
user str: has
reversed: sah
user str: fleas
reversed: saelf
user str: d
查看一下,如果您有任何其他问题,请告诉我。