2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 01:04 
Всем привет!

Значит так. В обозначенной в заголовке книге имеется упражнение за номером 1.9, вот его текст:
Цитата:
Напишите программу для копирования входного потока в выходной с заменой каждой строки, состоящей из одного или нескольких пробелов, одним пробелом.

Такая задача решаема с использованием только функций getchar() и putchar()? Дело в том, что меня сильно смущает словосочетание "... каждой СТРОКИ...". Может быть вместо "каждой строки" следует читать "каждой последовательности символов"? (я порыскал в инете и нашёл более старый перевод, в котором так и написано)

PS
т.е. если всё же прочитать вместо "строки" - "последовательности символов", то решение задачи заключается в следующем:
Код:
#include <stdio.h>

main() {
  int c;
 
  while ((c=getchar()) != EOF) {
    if (c == ' ') {
      while ((c=getchar()) == ' ');
      putchar(' ');
    }
    putchar(c);
  }
}


Я правильно понимаю?

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 01:33 
В английском издании написано буквально следующее:
Цитата:
Exercise 1-9. Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.
Т.о., под строкой понимается именно последовательность символов (если бы имелась в виду строка текста, заканчивающаяся символом '\n', было бы 'line', а не 'string').

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 01:44 
Аватара пользователя
А что мешает и со строками (которые line) так же поступить? Считать число пробелов от начала строки в еще одной переменной и выводить их или нет, в зависимости от того, что до конца строки встретится.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 01:48 
dnoskov в сообщении #285521 писал(а):
Код:
#include <stdio.h>

main() {
  int c;

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

Я правильно понимаю?

Правильно, только если за пробелом идёт символ EOF, его (этот символ EOF) выводить не надо.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 02:05 
covax
Я тоже подумал о чём-то похожем, но мне кажется что это велосипедом попахивает.
(Тем более, что косячным оказывается перевод. Т.е. авторы не хотели сразу давать такую алгоритмическую мясорубку (если сравнить с остальными задачами из этого подраздела))

Maslov
Спасибо за разъяснение. Теперь стало гораздо понятнее.

Цитата:
...только если за пробелом идёт EOF, его выводить не надо.

Я же не могу внутри цикла, условием выполнения которого является неравенство EOF, проверить переменную на равенство EOF (т.е. могу, но это же, как говорится, senseless? Или я чего-то не догоняю?)

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 02:30 
Можете, вы ведь эту же переменную и внутри цикла меняете.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 02:38 
dnoskov в сообщении #285528 писал(а):
Я же не могу внутри цикла, условием выполнения которого является неравенство EOF, проверить переменную на равенство EOF (т.е. могу, но это же, как говорится, senseless? Или я чего-то не догоняю?)
У Вас же внутри основного цикла (у которого, действительно, условием завершения является конец файла) есть ещё один цикл (где Вы пробелы дочитываете), в котором никаких проверок на конец файла уже нет.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 15:56 
А для чего вызывать функцию getchar() два раза?
Можно же сделать так:
Код:
#include <stdio.h>

main()
{
   int c, space = 0;
   while ((c = getchar()) != EOF)
   {
      if(space == 0 || c != ' ')
      {
         putchar(c);
         if(c == ' ')
            space = 1;
         else
            space = 0;
      }
   }
   return 0;
}


 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 16:03 
Тогда уж можно и ещё проще:
Код:
#include <stdio.h>

main()
{
    int c, pc = 0;
    while ((c = getchar()) != EOF) {
        if(c != ' ' || pc != ' ')
            putchar(c);
        pc = c;
    }
    return 0;
}

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение05.02.2010, 14:49 
Операция "Или" вводится в следующем подразделе, так что на момент написания этой программки мы о ней ещё не знаем.


Maslov
И действительно! Спасибо за разъяснения.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение05.02.2010, 18:26 

(Оффтоп)

dnoskov в сообщении #285904 писал(а):
Операция "Или" вводится в следующем подразделе, так что на момент написания этой программки мы о ней ещё не знаем.

В кулинарном техникуме: "Ты зачем морковку в суп положил? Мы морковку ещё не проходили!" :)

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение08.02.2010, 19:21 
Тоже столкнулся с этой задачей. Получилось как-то так:

Код:
#include <stdio.h>

main()
{
    int c;
 
    while ((c=getchar()) != EOF)
    {
        if (c == ' ')
        {
            while (getchar() == ' ');
        }
        putchar(c);
    }
}


Первый пробел присваивается переменной c, а остальные пропускаются во вложенном цикле.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение08.02.2010, 20:10 
bee в сообщении #286554 писал(а):
Тоже столкнулся с этой задачей. Получилось как-то так:
Первый непробельный символ после серии пробелов вообще не выводится.

 
 
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение12.02.2010, 13:15 
bee
Я подозреваю (и при проверке оказывается что так оно и есть), что из-за того, что во вложенном цикле нет присвоения c, будет пропускаться каждый первый "непробел" после серии пробелов.

Кроме того. Нашёл интересный, но опасный ресурс: http://users.powernet.co.uk/eton/kandr2/
Смотрите с осторожностью - отбивает охоту думать самостоятельно (хотя мне он местами помог (например в задачах про гистограммы - уж совсем не знал как к ним подойти))

 
 
 [ Сообщений: 14 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group