Ограничить пробелы до одного в тексте - c

Я читаю через K&R, и вопрос заключается в следующем: написать программу, чтобы скопировать ее входные данные на свой выход, заменяя каждую строку одного или нескольких пробелов одним пробелом. Я думаю, что знаю, что мне нужно сделать, настроить логическое значение, чтобы знать, когда я в космосе или нет. Я пытался и не удалось. Я нашел этот код, и он работает, я изо всех сил пытаюсь выяснить, что мешает писать пространство. Я думаю, что у меня может быть это, но мне нужно разъяснение.

#include <stdio.h>

int main(void)
{
  int c;
  int inspace;

  inspace = 0;
  while((c = getchar()) != EOF)
  {
    if(c == ' ')
    {
      if(inspace == 0)
      {
        inspace = 1;
        putchar(c);
      }
    }

    /* We haven't met 'else' yet, so we have to be a little clumsy */
    if(c != ' ')
    {
      inspace = 0;
      putchar(c);
    }
  }

  return 0;
}

Я создал текстовый файл для работы, текст гласит:

so this    is where    you have been

После 's' на 'this' состояние меняется на 1, потому что мы находимся в пространстве. Пробел записывается, и читается следующий пробел. Итак, теперь мы входим:

while((c = getchar()) != EOF)
      {
        if(c == ' ')
        {
          if(inspace == 0)
          {
            inspace = 1;
            putchar(c);
          }

Но inspace не 0, а 1. Так что же происходит? Код пропускает, возвращая 0;, ничего не записывая и просто продолжает цикл while? вернуть 0; находится вне цикла, но это единственный способ увидеть, что значение не возвращается.

4 ответа

Решение

С этой точки зрения:

if(c == ' ')
{
   if(inspace == 0) // <-- here

Если inspace равно 1, он не будет выполнять тело if, он перейдет к:

if(c != ' ') { 

И до тех пор, пока c == ' ' выше будет ложным, он пропустит тело if и перейдет к:

while((c = getchar()) != EOF) {

И это будет продолжаться до конца файла или до (c != ' ') оценивает как истинное. Когда с не является пробелом:

 if(c != ' ')
 {
   inspace = 0;
   putchar(c); 

пробел обнуляется, и символ печатается.

Когда inspace равен 1, а c - это выражение:

inspace == 0

оценивает в 0 и код

inspace = 1;
putchar(c);

не исполняется.

Затем программа перейдет к следующей итерации цикла while, если сможет, но не вернет 0, пока цикл while не закончится.

Вы можете упростить цикл while для этого кода:

while((c = getchar()) != EOF)
{
  if(c == ' ')
  {
    if(inspace == 0)
    {
      inspace = 1;
      putchar(c);
    }
  } else
  {
    inspace = 0;
    putchar(c);
  }
}

Если условие в операторе if не является истинным, следующее выражение не выполняется. Это означает, что все внутри соответствующих скобок пропускается, и выполнение возобновляется "после" закрывающей скобки.

Поскольку следующий оператор if также ложен, внутри этой итерации цикла for ничего не делается.

Да, в случае, который вы упомянули, он ничего не записывает и продолжает цикл while и получает следующий символ. Если следующий символ снова будет пробелом, он будет делать то же самое, то есть перейти к следующей итерации без печати. Всякий раз, когда он находит первый не пробел, он устанавливает значение пробела в 0 и начинает печать.

Цикл while будет прерываться всякий раз, когда getchar будет вызывать EOF. Тогда программа вернет 0.

Другие вопросы по тегам