2016-12-14 4 views
-1

У меня есть эта программа:Пробелы не печатает правильно

int main(void) 
{ 
    while ((c = getchar()) != EOF) { 
     putchar(c); 
     if (c == '{') 
      spaces += 4; 
     else if (c == '}') 
      spaces -= 4; 
     else if (c == '\n') { 
      print_spaces(spaces); 
      while ((c = getchar()) == ' ') 
       continue; 
      putchar(c); 
     } 
    } 
} 

void print_spaces(int spaces) 
{ 
    while (spaces-- > 0) 
     putchar(' '); 
} 

При запуске с этим входом:

#include<stdio.h> 
int main(void) 
{ 
printf("hello, world!\n"); 
} 

Он просто печатает точный ввод, вместо требуемого выходного - желаемый выходной бытии:

#include<stdio.h> 
int main(void) 
{ 
    printf("hello, world!\n"); 
} 

Где я пошла не так?

+1

Отслеживать его в отладчике – KevinDTimm

+0

@KevinDTimm. Ошибка сегментации. –

+3

Отладчик может использоваться для перехода через код и посмотреть, выполняет ли он то, что вы ожидаете, изучать переменные и т. Д. –

ответ

1

В конце условия while есть ;, возможно, это преднамеренное, но очень вводящее в заблуждение: это похоже на ошибку. Вы должны добавить continue заявления или пустой блок {} подчеркнуть пустое заявление, как намеренное:

while ((c = getc(f)) == ' ') 
     continue; 

Есть некоторые проблемы в своем подходе:

  • следует уничтожать в зародыше последних байт, если это не EOF, поэтому его можно протестировать в основном цикле. Это причина вашей проблемы: { только что скопирован после того, как \n и spaces не увеличивается.
  • Вы также должны пропускать символы табуляции и обрабатывать новые строки специально, иначе пустая строка будет препятствовать правильному отступу следующей строки.
  • линии, которые не должны ; прекращенные вызвать продолжениями с отступом, потенциально на определенную величину, чем другой 4.

Здесь улучшенный фрагмент кода, который рассматривает только первые 2 вопроса:

while ((c = getc(f)) != EOF) { 
    putchar(c); 
    if (c == '{') { 
     spaces += 4; 
    } else 
    if (c == '}') { 
     if (spaces >= 4) { 
      spaces -= 4; 
     } 
    } else 
    if (c == '\n') { 
     /* consume all white space except newlines */ 
     while (isspace(c = getc(f))) { 
      if (c == '\n') 
       putchar(c); 
     } 
     if (c != EOF) { 
      ungetc(c, f); 
      /* print the indentation if further code is present */ 
      print_spaces(spaces); 
     } 
    } 
} 
+2

Я думал, что это было намеренно, проглотить любые пробелы в файле и заменить его на то, что предоставляется 'print_spaces'. Я согласен, что стиль субоптимальный :). – cxw

+0

Нет, это было намеренно. –

+0

@Redesign: Хорошо, я был вне базы как в диагностике, так и в лечении ... Я обновил ответ на актуальные проблемы. – chqrlie

4

Это потому, что символ { считывается через вашу строку while ((c = getc(f)) == ' '); в символьном блоке новой строки. Поэтому условие c == '{' никогда не достигалось, а счетчик пробелов никогда не увеличивался.

Насколько я вижу, есть две вещи здесь:

  1. Углубление зависит от двух последовательности символов \n{ для отступа и \n} к разрегистрировали отступа. Вам нужно каким-то образом передать то, что имеет предыдущий или следующий символ (newline ниже).
  2. } и { имеют слегка разностную парадигму, т.е.печать и приращение против декремента и печати (вроде как i++ против ++i

ниже код пытается захватить эти две точки

  1. изменение последовательности настройки пространства счетчика и печать
  2. с помощью переменной для передачи предыдущего символа

Это, как говорится, очень рудиментарно, не обрабатывает угловые шкафы или стиль кодирования и m Вероятно, есть более элегантный способ сделать это.

`

10  int newline = 0; 
11  while ((c = getc(f)) != EOF) { 
12   if (c == '}') { 
13    spaces -= 4; 
14   } 
15   if (newline == 1) { 
16    print_spaces(spaces); 
17    newline = 0; 
18   } 
19   putchar(c); 
20   if (c == '{') { 
21    spaces += 4; 
22   } else if (c == '\n') { 
23    newline = 1; 
24    while ((c = getc(f)) == ' '); 
25    ungetc(c, f); 
26   } 
27  } 

`

+0

Это останавливается после первого '{\ n'. –

0

Ваш код это немного сбивает с толку.

int printspaces = 1; // initial spaces are ignored. 
while ((c = getc(f)) != EOF) { 
    if(printspaces == 1) 
    { 
     print_spaces(spaces); 
     printspaces = 0; 
     if(c == ' ') 
      while((c = getc(f)) == ' '); 
    } 
    putchar(c); 
    switch(c) 
    { 
     case '{': 
      spaces += 4; 
      break; 
     case '}': 
      if(spaces >= 4) 
       spaces -= 4; 
       break; 
     case '\n': 
      printspaces = 1; 
      break; 
     default: 
      break; 
    } 
} 
+0

интересный альтернативный подход, но он имеет ту же проблему, что и '{', который следует за '\ n', обрабатывается неправильно. Даже если эта проблема исправлена, программа не может правильно отступать, так как фразы 'case' и' default' будут иметь тот же отступ, что и код внутри блока switch'. – chqrlie

+0

Да, я исправил его. – cpatricio

+0

Ваш код вызывает дополнительный вопрос: должны ли пропущенные или скопированные начальные пробелы? – chqrlie

Смежные вопросы