【问题标题】:Input string of unknown length未知长度的输入字符串
【发布时间】:2018-04-14 08:14:28
【问题描述】:

我编写了这个程序,用“*”替换两个空格。

如何修改代码以使其无论字符串大小如何都能执行相同的操作?甚至可以只使用putchargetchar吗?

#include <stdio.h>

int c;             
char buffer[256];  
int counter= 0;    
int i;             

int main()
{

while ((c = getchar()) != '\n'&&c!=EOF) {  

    buffer[counter] =c;
    counter++;

    if (counter >=255) {
        break;
    }
 }

 for(i=0; i<256; i++) {

    if(buffer[i]== ' '&&buffer[i+1]==' ')
    { 

        buffer[i]= '*';

        putchar(buffer[i]); 

        i = i + 2; 

        continue; 
    }
    putchar(buffer[i]); 
}

putchar('\n'); 
return 0;
}

【问题讨论】:

  • 小心,getchar 返回一个 int,这对于 EOF 检查实际上很重要。您可能也不应该将EOF 放在缓冲区中。请记住,如果输入的行小于 256 个字符,那么 buffer 的其余元素将是 indeterminate (并且看似随机),并且在打印输入时不应使用 then。
  • 所以我已经编辑了代码,但我仍然不清楚我应该如何实现代码来读取和输入未知长度的字符串
  • 您的编辑使您的 while 循环无限。 || 应该是 &amp;&amp;。否则,要打破循环c 必须同时是'\n' EOF,这是不可能的。
  • 哦,谢谢。 @WhozCraig 你能否给我一个关于如何实现代码来做同样事情的提示,不管输入字符串的大小是多少?我只是不明白它应该如何工作
  • 你为什么还要存储完整的输入?对于您的用例来说,大小为 2 的环形缓冲区还不够吗?

标签: c arrays if-statement input


【解决方案1】:

问题陈述不需要您将完整的输入存储在缓冲区中。关于输出什么字符的决定仅取决于输入的最后两个字符。考虑以下代码:

#include <stdio.h>

int main(void)
{
  // two variables for the last two input characters
  int c = EOF, last = EOF;
  while ((c = getchar()) != EOF)
    {
      // if both are a space, store a single '*' instead
      if (c == ' ' && last == ' ')
        {
          c = '*';
          last = EOF;
        }
      // print the output, and shift the buffer
      if (last != EOF)
        putchar(last);
      last = c;
    }
  // take care of the last character in the buffer after we see EOF
  if (last != EOF)
    putchar(last);
}

根本不需要 malloc 和朋友。这是一个很好的例子,需要您在编写代码之前仔细考虑,以免在缓冲区上浪费不必要的资源。

【讨论】:

  • last = c 如何移动缓冲区?我不太明白
  • 好吧,也许有一种更聪明的方法可以做到这一点,但我们的想法是将输入的当前字符存储在c,之前的字符存储在lastlast = c 只是意味着在从 getchar 获取下一个输入之前将当前的保存为最后一个。
  • 代码并不重要,只是为了说明不需要大缓冲区。
  • 好的,最后一个问题是要修改我的原始代码,以便打印未知大小的输出吗?还是我可以完全丢弃我的原始代码?
  • 我相信你可以放弃你的第一个循环并修改你的第二个循环来工作。 :)
【解决方案2】:

仅用于打印的代码:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    char prev = EOF, curr;
    while ((curr =(char)getchar()) != '\n' && curr != EOF) 
            {  

                if(curr==' '&&prev==' ')
                {
                    curr = '*';
                    prev = EOF;

                }
                if (prev != EOF)
            putchar(prev);
        prev = curr;
            }
            putchar(prev);
    return 0;
}

使用realloc 实际更改字符串:

#include <stdio.h>
#include <stdlib.h>

    int main() {
        unsigned int len_max = 128;
        char *m = malloc(len_max);
        char c;             
        int counter= 0;    
        int i;
        int current_size = 256;
                printf("please input a string\n");
                while ((c = getchar()) != '\n' && c != EOF) 
                {  

            m[counter] =(char)c;
            counter++;
            if(counter == current_size)
            {
                        current_size = i+len_max;
                m = realloc(m, current_size);
            }

                }


         for(i=0; i<counter; i++) 
         {

            if(m[i]== ' '&&m[i+1]==' ')
            { 
                m[i]= '*';
                putchar(m[i]); 
                i = i + 2; 
                continue; 
            }
            putchar(m[i]); 
        }

        putchar('\n'); 
        free(m);
        m = NULL;
        return 0;
    }

【讨论】:

  • 感谢您的回答,但对于我的练习,我只能使用 putchar、getchar、while 循环和 ifs,我应该在前面提到过。有可能吗?
  • 你的意思是你不能使用realloc
  • 是的,我不能我一直在尝试一整天,但我似乎无法做到这一点
  • 我的意思是你可以使用realloc吗?
  • 那么长度为 2 的缓冲区就足够了
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 2013-01-23
  • 1970-01-01
相关资源
最近更新 更多