Редактирование входного потока. (ansi c)

Модератор: Модераторы разделов

Аватара пользователя
j3nny
Сообщения: 11

Редактирование входного потока.

Сообщение j3nny »

Здравствуйте.
Читаю книгу Кернигана и Ричи(c pr. lang.), в первой же главе наткнулся на задачу:

2)Напишите программу, копирующую символы ввода в выходной поток и заменяющую стоящие подряд пробелы на один пробел.

Так вот в чем вопрос:как заменить стоящие рядом пробелы,если их кол-во не известно заранее?
пробовал это(ясно почему не работает, но не представляю себе как по другому то?!):

Код: Выделить всё

#include <stdio.h>
main()
{
int s,c;
while((s=getchar())!=EOF) {
++c;
if((s[c]==' ')&&(s[c+1]=='  ')) s[c+1]='\b';/*убираем последний пробел*/
putchar(s);
}
}
Спасибо сказали:
Аватара пользователя
sergius
Сообщения: 782

Re: Редактирование входного потока.

Сообщение sergius »

Выводим строку по-символьно, если предыдущий и текущий символы пробелы, текущий пропускаем.
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Редактирование входного потока.

Сообщение powerfox »

Код: Выделить всё

#include<stdio.h>

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

}

Суть в том, что читается символ, в том чисте и пробел, все последующие пробелы игнорируются(второй цикл).
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: Редактирование входного потока.

Сообщение elide »

powerfox, у тебя по одному символу в начале слова теряется, как и перевод строки, если она заканчивается на пробел, потому что на границе слова два раза подряд делается getchar();
ты мне очень ценный совет дал. надо думать, что пишешь....
чтож сам-то не пользуешься? а туда же, лезешь советы давать. нехорошо.

j3nny

Код: Выделить всё

#include <stdio.h>
int main(){
        char prev = 0, curr;
        while( (curr = getchar()) != EOF )
                if( curr != ' ' || prev != ' ')
                        putchar(prev = curr);
        return 0;
}
слава роботам!
Спасибо сказали:
Аватара пользователя
j3nny
Сообщения: 11

Re: Редактирование входного потока.

Сообщение j3nny »

Всем спасибо, elide, все работает, но я что-то недопонял в исходнике...
Идет цикл -> если данный символ не равен 0 и предыдущий тоже не равен 0(как машина определяет что prev отвечает за предыдущий символ?) -> она выводит ... Что она выводит?
Спасибо сказали:
rpv
Сообщения: 28
ОС: Ubuntu

Re: Редактирование входного потока.

Сообщение rpv »

Это мой вариант, немного кривой, но работает:

#include <stdio.h>

int main()
{
int s, n;
s = 0;
while ((n = getchar()) != EOF)
{
if ((n == ' ') && (s == 0))
{
s = 1;
putchar(n);
}
else if (n != ' ')
{
s = 0;
putchar(n);
}
}
return 0;
}
Ubuntu 6.10 и WinXP - вот как-то так...
Спасибо сказали:
Аватара пользователя
j3nny
Сообщения: 11

Re: Редактирование входного потока.

Сообщение j3nny »

rpv, огромное спасибо, тут все ясно!
Но все же хотелось бы понять как работает исходник elide'а...
Спасибо сказали:
Аватара пользователя
VAMonster
Сообщения: 15

Re: Редактирование входного потока.

Сообщение VAMonster »

1) Определяем переменные curr и prev
2) Считываем по символьно до конца файла
3) Если и curr, и prev не пробелы - выводим. Здесь же присваиваем prev значение curr
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: Редактирование входного потока.

Сообщение elide »

ну а что ту непонятного?

while( (curr = getchar()) != EOF ) // читаем посимвольно до конца файла
if( curr != ' ' || prev != ' ') // если текущий или предудущий символ - не пробел, то
putchar(prev = curr); // выводим текущий символ, и сохраняем его в переменную prev, чтоб потом принять его за предыдущий...
слава роботам!
Спасибо сказали:
rpv
Сообщения: 28
ОС: Ubuntu

Re: Редактирование входного потока.

Сообщение rpv »

Для j3nny

Насчет исходника от elide
1) Разберись с логическами выражениями
2) Операция присваивания тоже дает результат, т.е. операция prev = curr даст результат curr, поэтому putchar(prev = curr) выведет curr и присвоит prev значение curr

Вообще-то я сам новичек в программировании и сайчас читаю эту книгу. В исходнике от elide сам долго разбирался :)
Ubuntu 6.10 и WinXP - вот как-то так...
Спасибо сказали:
Аватара пользователя
j3nny
Сообщения: 11

Re: Редактирование входного потока.

Сообщение j3nny »

elide,rpv большое спасибо.непонятно оказалось что getchat(prev= curr) не только выводит, но еще и сохраняет значение... Еще раз спасибо.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Редактирование входного потока.

Сообщение t.t »

2elide: у тебя одна маленькая ошибка: prev нужно инициализировать, пробелом либо не-пробелом в зависимости от того, хотим ли мы, чтобы усекались все пробелы в начале текста или чтобы один оставался. Исходя из условия задачи мне кажется, что правильнее будет инициализировать не-пробелом. А так это лотерея; выстрелит, конечно, вряд ли, но если строго, то всё же.

rpv, огромное спасибо, тут все ясно!
Но все же хотелось бы понять как работает исходник elide'а...
А мне наоборот: у elide всё ясно, а у rpv я запутался :)
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
j3nny
Сообщения: 11

Re: Редактирование входного потока.

Сообщение j3nny »

Чем меньше опыта, тем лучше понимаешь проще написанный исходник имхо :)
Спасибо сказали:
Аватара пользователя
powerfox
Сообщения: 458

Re: Редактирование входного потока.

Сообщение powerfox »

elide писал(а):
13.11.2005 15:20
powerfox, у тебя по одному символу в начале слова теряется, как и перевод строки, если она заканчивается на пробел, потому что на границе слова два раза подряд делается getchar();
ты мне очень ценный совет дал. надо думать, что пишешь....
чтож сам-то не пользуешься? а туда же, лезешь советы давать. нехорошо.


Спасибо, не видел этой ошибки: когда проверял печатал "asd dfsd sdf e we we eww we" - поэтому и не заметил, лень было нормально проверять.
Совет(теперь самому себе): тестировать нужно, думая :( , что пишешь.
Спасибо сказали: