【问题标题】:Solving KNKING exercise 14, chapter 8. Reverse the words解决 KNKING 练习 14,第 8 章。反转单词
【发布时间】:2021-05-13 05:14:30
【问题描述】:

我正在阅读 K.N.King C 编程,但我有一个问题。

我正在解决项目 5,第 12 章,它是使用指针从第 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 = '\0';
    
    while(p >= arr)
    {
        while(*--p != ' ' && p != arr);
        q = p == arr ? arr : p + 1;
        
        while(*q != '\0' && *q != ' ')
        {
            printf("%c", *q++);
        }
        if(p >= arr)
            printf(" ");
        
    }
    printf("\b%c", mark);
    printf("\n");
}


问题是如果我输入一个句子“我的名字叫 jiyong!”,预期的输出是“jiyong is name My!”但输出总是有'\xxx'。我怎样才能摆脱?这些'\xxx'是什么东西?

在 Xcode 12.4 下运行

【问题讨论】:

  • 您在最后的标点符号前输出一个退格 (\b)。为什么?
  • 因为会有额外的空格“jiyong is name My!”
  • 我建议你通过调试器运行这个程序来找出问题所在。但是,我看不出有什么好的理由使用退格键来删除一开始就不应该输出的字符。也许将p &gt;= arr 更改为p &gt; arr 会更有意义?
  • 好的。谢谢你帮助我!我会努力的!
  • 一个小疏忽:您正确地考虑了可能的溢出并添加了一个条件 (p &lt; arr + N) 来防止它,但您没有考虑这种事件的影响。事实证明,mark 变量在这种情况下仍然是 0,这会导致您在换行符之前使用 printf 一个 NUL 字符。这可能不是预期的效果。

标签: c


【解决方案1】:

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

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

    while((c = getchar()) != '\n' && p < arr + N)
    {
    
        if(c == '?' || c == '.' || c == '!')
        {
            mark = c;
            break;
        }
        else
            *p++ = (c == ' ') ? '\0' : c;
    }
    *p = '\0';

然后我们可以向后查找单词并将它们打印为字符串,而不是遍历它们的字符:

    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 在第一个循环中至少增加一次,即输入行永远不会为空。但这似乎是一个有效的假设(虽然不是很安全),因为输入被定义为“一个句子”,所以它不应该为空...

【讨论】:

  • @Sanchez 感谢您纠正我的错误!
  • 我刚刚学会了指针的东西……我很高兴我能修复一些东西 XD 谢谢你的解决方案。惊讶于代码的整洁程度!
猜你喜欢
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2013-04-15
  • 2015-02-22
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多