getChar()从C中的段落中删除一个单词

时间:2018-04-02 20:08:06

标签: c getchar

假设我有一个段落,在该段中我想删除单词bus。我使用getchar()来获取输入。我该怎么做呢。

int main()
{

 while ((character = getchar()) != EOF) {
    if (character != '\n') {

1 个答案:

答案 0 :(得分:0)

First Things First

您尝试解决的问题(从较大的字符串中删除子字符串)是一个非常常见的问题。在寻求答案之前,它可以帮助做一些研究。通常当问题很常见时,可以使用库和工具为您完成工作。

在这种情况下,您要解决的问题称为字符串替换。字符串替换是以下过程:

  • 取一串文字
  • 扫描匹配的子字符串
  • 将匹配替换为其他子字符串(在您的情况下,没有任何内容)

因此,在伪代码中你要做的是:

string paragraph = "This is a paragraph about a bus. I like the bus. My friend doesn't.";
replace(paragraph, "bus", "");

请注意,子字符串删除只是子字符串替换的子集。您可以像“牛”一样轻松地替换“公共汽车”,创建新的字符串“这是一个关于母牛的段落。我喜欢牛。我的朋友没有。”

谷歌搜索“C ++字符串替换”将教你一些关于如何做到这一点

C字符串与C ++字符串

在C中,数据存在于所谓的基本类型中。这基本上意味着每种类型的数据都有一些直接映射到RAM。 RAM中的整数是4个字节。 5个整数的数组在RAM中是20个字节,每个第4个表示一个新的整数。字符是单个字节,字符串是字符数组。很简单,是吗?

在C ++中,对象的概念成为该语言的关键部分。在较低级别,这些使用指针来抽象出RAM中发生的事情。我将避免使用指针上的课程,而是为您提供对象的初学者定义:对象允许您将数据和行为组合到一个概念中。这意味着不是只有一个字符数组,而是有一个“字符串” - 而“字符串”有一组与字符串相关的函数(比如连接它们或执行字符串替换)

这是一个可以在任何图灵完整编程语言中解决的问题,但如果您被允许使用C ++,那么您会发现代码更容易阅读和理解。

getchar()

的问题

使用getchar()时,您一次只能看到一封信。这意味着我们永远不会完整地看到字符串,因此我们不能只使用复制和粘贴字符串替换算法。如果您没有 使用getchar(),那么我建议您以其他方式读取字符串,以便整个段落可以存储在一起。例如:

<强> C:

char buff[1024];
fgets(buff, 1024, stdin)

<强> C ++:

string paragraph;
cin >> paragraph;

通过这种方式,您可以一次获得整个字符串而不是一个字母

如果必须使用getchar()

即使一次读取一个字符仍然可以,但它需要有限状态机。有限状态机背后的想法是通过跟踪当前的“状态”来跟踪已经看到的内容

例如:

州1:

  • 如果此字符为B,请转至州2.否则,请保持此状态。

州2:

  • 如果此字符为U,请转到状态3.否则,请转到状态1.

状态3:

  • 如果此字符为S,我们会遇到bus一词!
  • 否则,请转到州1

这里有一些我认为可以实现你想要的伪代码,但我建议你考虑切换到C ++字符串,而不是在可能的情况下这样做:

int main()
{
    int state = 1;
    char buff[1024];
    int i = 0;
    memset(buff, 0, 1024);
    while ((character = getchar()) != EOF)
    {
        switch(state)
        {
            case 1:
                if (character == 'b')
                {
                    state = 2;
                }
                else
                {
                    buff[i] = character;
                    i++;
                }
                break;
            case 2:
                if (character == 'u')
                {
                    state = 3;
                }
                else
                {
                    // We didn't add the "b" earlier, so add it now
                    buff[i] = 'b';
                    buff[i + 1] = character;
                    i += 2;
                    state = 1; // <-- The bug I mention below... This line was missing
                }
                break;
            case 3:
                if (character == 's')
                {
                    // We found (and ignored) one occurrence of the word "bus"
                    // Now let's start looking for the next one
                    state = 1;
                }
                else
                {
                    // We didn't add the "bu" earlier, so add it now
                    buff[i] = 'b';
                    buff[i + 1] = 'u';
                    buff[i + 2] = character;
                    i += 3;
                    state = 1; // <-- The bug I mention below... This line was missing
                }
                break;
        }
    }
    // Let's print our buffer now
    printf("%s", buff);
    return 0;
}

修改

我刚刚重新阅读了我的答案,并在我的代码中发现了一个错误。这是一个很好的例子,说明为什么你应该尝试使用更高级别的抽象而不是一次处理一个角色。代码越低级,就越容易犯错误 - 因为我们在代码中所做的事情并没有直接映射到我们对问题的看法。在适当的抽象层次上,问题和代码的英文定义应该看起来几乎相同。

具体来说,我的错误是如果字母与预期的字母不匹配,我没有将状态设置为1 。这个错误很容易被忽略,因为人类通常不会考虑有限状态机。我们只是说“找到公共汽车一词的所有实例”。

顺便说一句,如果您被允许使用C ++字符串而不需要使用getchar()函数,那么这是代码:

int main()
{
    string paragraph;
    cin >> paragraph;
    paragraph.replace("bus", "");
    cout << paragraph << endl;
    return 0;
}