2014 dxdy logo

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

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




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


15/06/09
154
Самара
Всем привет!

Значит так. В обозначенной в заголовке книге имеется упражнение за номером 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 
Заслуженный участник


09/08/09
3438
С.Петербург
В английском издании написано буквально следующее:
Цитата:
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 
Аватара пользователя


25/03/09
94
А что мешает и со строками (которые line) так же поступить? Считать число пробелов от начала строки в еще одной переменной и выводить их или нет, в зависимости от того, что до конца строки встретится.

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 01:48 
Заслуженный участник


09/08/09
3438
С.Петербург
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 


15/06/09
154
Самара
covax
Я тоже подумал о чём-то похожем, но мне кажется что это велосипедом попахивает.
(Тем более, что косячным оказывается перевод. Т.е. авторы не хотели сразу давать такую алгоритмическую мясорубку (если сравнить с остальными задачами из этого подраздела))

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

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

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

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 02:30 
Заслуженный участник


04/05/09
4587
Можете, вы ведь эту же переменную и внутри цикла меняете.

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 02:38 
Заслуженный участник


09/08/09
3438
С.Петербург
dnoskov в сообщении #285528 писал(а):
Я же не могу внутри цикла, условием выполнения которого является неравенство EOF, проверить переменную на равенство EOF (т.е. могу, но это же, как говорится, senseless? Или я чего-то не догоняю?)
У Вас же внутри основного цикла (у которого, действительно, условием завершения является конец файла) есть ещё один цикл (где Вы пробелы дочитываете), в котором никаких проверок на конец файла уже нет.

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение04.02.2010, 15:56 


25/01/10
33
А для чего вызывать функцию 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 
Заслуженный участник


04/05/09
4587
Тогда уж можно и ещё проще:
Код:
#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 


15/06/09
154
Самара
Операция "Или" вводится в следующем подразделе, так что на момент написания этой программки мы о ней ещё не знаем.


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

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение05.02.2010, 18:26 
Заслуженный участник


26/07/09
1559
Алматы

(Оффтоп)

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

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

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


08/02/10
1
Тоже столкнулся с этой задачей. Получилось как-то так:

Код:
#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 
Заслуженный участник


09/08/09
3438
С.Петербург
bee в сообщении #286554 писал(а):
Тоже столкнулся с этой задачей. Получилось как-то так:
Первый непробельный символ после серии пробелов вообще не выводится.

 Профиль  
                  
 
 Re: "Язык программирования C" Керниган и Ритчи (2010).
Сообщение12.02.2010, 13:15 


15/06/09
154
Самара
bee
Я подозреваю (и при проверке оказывается что так оно и есть), что из-за того, что во вложенном цикле нет присвоения c, будет пропускаться каждый первый "непробел" после серии пробелов.

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group