解决KNKING练习14,第8章.把单词倒过来



我正在阅读k.n.k king的C编程,我对它有一个问题。

我正在解决第12章的项目5,即使用指针修改第8章的项目14。

8.14项目写一个程序把句子中的单词颠倒过来:

输入一句话:你可以把燕子关起来,不是吗?

倒装句:你不能吞下笼子,是吗?

提示:使用循环读取将字符一个一个地存储在一维字符中数组中。循环是否在句号、问号或感叹号处停止点("终止字符"),保存在单独的字符中变量。然后使用第二个循环向后搜索数组最后一个词的开头。打印最后一个单词,然后搜索倒着读倒数第二个单词。重复,直到开始到达数组。最后,打印结束字符。

#include <stdio.h>
#include <ctype.h>
#define N 100

int main()
{
char arr[N] = {0};

char *p, *q, mark = 0;
int c;
p = arr;

while((c = getchar()) != 'n' && p < arr + N)
{

if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = c;
}
*p = '';

while(p >= arr)
{
while(*--p != ' ' && p != arr);
q = p == arr ? arr : p + 1;

while(*q != '' && *q != ' ')
{
printf("%c", *q++);
}
if(p >= arr)
printf(" ");

}
printf("b%c", mark);
printf("n");
}

问题是如果我输入一个句子"我的名字是吉勇!",预期输出是"吉勇是我的名字!"但是输出总是带有'xxx'。我怎样才能摆脱?这些"xxx"是什么?

在Xcode 12.4下运行

第二个循环在我看来太复杂了。您需要向后扫描字符串并打印找到的每个单词,对吗?但是不需要记住整个句子…?

因此我们可以用零替换每个空格字符,从而终止每个单词。

while((c = getchar()) != 'n' && p < arr + N)
{

if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = (c == ' ') ? '' : c;
}
*p = '';

则可以反向查找单词并将其打印为字符串,而不是遍历其字符:

while(--p > arr)    // all words except the first one
{
if(!*p && p[1]) //p[1] or *(p + 1)
printf("%s ", p+1);
}
printf("%s", arr);  // the first word goes last
if(mark)
printf("%c", mark);
printf("n");

我假设p在第一个循环中至少增加一次,即输入行从不为空。但这似乎是一个有效的假设(尽管不是很安全),因为输入被定义为"一个句子",所以它不应该为空…

最新更新