IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> ЗАДАЧА С ФАЙЛОМ
Vlad
сообщение 21.05.2009 14:14
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


Здравствуйте, помогите, пожалуйста решить задачку по паскалю. У меня курсовая в понедельник, а я немогу разобраться! ПОЖАЛУЙСТА!!!


Дано символьный файл f, найти количество слов в файле.

Сообщение отредактировано: Vlad - 21.05.2009 14:40
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 14:27
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Во первых, тебе сказали что заголовок должен быть информативным.Для данной темы подошло бы что то в духе "задача с файлом".Во вторых,не знаю как другим,но мня раздражает заголовок с капсом.А в третьих,процетирую
volvo
Цитата

Где ваш код?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Vlad
сообщение 21.05.2009 14:41
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


злые Вы sad.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 15:04
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Молодой человек,а вы что хотите,чтобы вы зашли, написали условие задачи и вам скинули код работающей программы.Тогда ,видимо, я должен вас разочаровать,потому что никто этого делать не станет.Ладно я такой же студент и стиль написания у меня не ахти,но здесь есть програмисты со стажем,которые вам могут одну и ту же задачу решить 10 способами, используя разные констукции,а с вас потом все это спросят,а вы в эом ничего не понимаете и в итоге получите незачет.А вообще,то что вы спрашиваете это азы,если вы их не понимаете,то потом будет совсем тяжко,а всю жизнь на чужом горбу не выедеш.

Добавлено через 11 мин.
А теперь по сути.У вас есть файл со словами,что вы делаете, вы считываете элемент файла и проверяете есть ли он в множесте букв,если есть то берете следующий элемент и также проверяете до тех пор пока не наткнетесь на пробел,наткнулись на пробел, увеличили значение переменной считающей слова на +1 и выполняете данную операцию до конца файла.
Код

while not eof(fin) do
begin
  while ch in ['A'..'Z','a'..'z'] do{проверяем алфавит}
    read(fin,ch);{считываем элемент из файла fin и записываем в переменную ch}

S:=S+1;{Считаем слова}
end;

А инициализация файла и обьявление типов переменных,это уж будьте добры сами,если вы уж это не сможете сделать,то не быть вам програмистом.

Сообщение отредактировано: Krjuger - 21.05.2009 15:17
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Vlad
сообщение 21.05.2009 15:35
Сообщение #5


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


Так я же не прошу от begin к end всё писать, мне механизм понять нужно, остальное сделаю. good.gif Вот только не пойму как этот кусочек пробел определяет!? blink.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 15:44
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


То что я написал онон не пробел определяет,а проверяет алфавит,все символы не входящие в английский алфавит воспринимаются как разделители слова.если надо конкретно пробел,то будет так.
Код

while not eof(fin) do
begin
  while ch <> ' ' do {до тех пор пока наш элемент все кроме пробела читаем следующий,как только робел переходим к следующему слову и увеличиваем S на 1.}
    read(fin,ch);{считываем элемент из файла fin и записываем в переменную ch}

S:=S+1;{Считаем слова}
end;

В чем заключаются аномалии этого кода.На пример,Если у тебя 2 пробела подрят,то второй пробел воспримется,как слово,так что тебе надо бы создать рекурсивную процедуру удаления пробела.В первой реализации такая же проблема,поэтому, если у тебя нету четких правил по структуре самого файла,лучше весь мусол, попадающтйся между словами, рекурсивно удалять,иначе тебе уйму слов выдаст.Ну а так,если соблюдать правила заполнения файла,то все будет работать.Возможно сторожилы форума подскажут что нибудь пограмотнее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Vlad
сообщение 21.05.2009 16:08
Сообщение #7


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


вот наброски сделал, но не работает blink.gif


program lab_file;

uses crt;
var
words: file of string;
ch:char;
s:integer;
f:string;

begin
assign (words.txt,f);
while not eof(f) do begin
while ch <> ' ' do
read(f,ch);
S:=S+1;
end;
writeln(s);
end.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 16:27
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


И не будет работать.В assign надо указывать полный путь к файлу,в котором информация лежит.А вообще лучше бы, наверно, сделать так.

program lab_file;

uses crt;
var
fin: text;
ch:char;
s:integer;

begin
assign (fin,'C:\Tpascal\test.txt');{как пример}
while not eof(fin) do begin
while ch <> ' ' do
read(fin,ch);
S:=S+1;
end;
writeln(s);
end.


Во первых, нельзя так организовывать assign ,я даже не знаю как сказать,что за ерунду ты написал.А теперь должно работать,только укажи точный путь к файлу.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 21.05.2009 16:52
Сообщение #9


Гость






Цитата
тебе надо бы создать рекурсивную процедуру удаления пробела
Цитата
весь мусол, попадающтйся между словами, рекурсивно удалять
Что ты пристал с рекурсией? Не надо никакой рекурсии тут: читаем очередной символ. Если это буква (ну, как задать алфавит - разберешься) - то ничего не делать, если НЕ буква - увеличить счетчик слов и читать символы дальше, до тех пор, пока не встретится буква. Продолжить цикл до тех пор, пока не доберешься до конца файла. Все. Никаких рекурсий тут даром не надо.
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 17:12
Сообщение #10


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Ты посмотри(самый первый пост с кодом),я первый раз ему так и сделал,мы читали не до пробела,а пока буквы,но ему захотелось с пробелом,и вылез ему вариант с пробелом.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Vlad
сообщение 21.05.2009 18:14
Сообщение #11


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


ВСЁ ДОГНАЛ - СПАСИБО ЗА ПОМОЩЬ!!!


uses crt;
var
fin: text;
ch:char;
s:integer;
h:string;
begin
clrscr;
assign (fin,'D:\instal\PASCAL_7\tp7\prog\test.txt');
reset (fin);
while not eof(fin) do begin
readln(fin,h)
end;
writeln(h);
reset (fin);
while not eof(fin) do begin
if ch = ' ' then
S:=S+1;
read(fin,ch);
end;

close(fin);
write(S+1);
readln;
end.

Сообщение отредактировано: Vlad - 21.05.2009 18:30
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 21.05.2009 18:56
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Мда, ты явно не догнал.Во первых 2 раза ресет делать ненадо.И первого хватило.Во вторых ты не количество слов считаеш а количество пробелов.В третьих зачем ты собираеш весь файл в строку.сразу проходиш файл и выявляеш пробелы.Тебе лиш assign сделат надо было и все.Я тебе написал полностью работающую лабу,а ты начал что то там придумывать.Тебе только поменять путь к файлу надо было.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Vlad
сообщение 21.05.2009 19:10
Сообщение #13


Новичок
*

Группа: Пользователи
Сообщений: 13
Пол: Мужской
Реальное имя: Vlad

Репутация: -  0  +


считываю файл для того что бы вывести его содержимое на экран, а дважды ресет, потому что курсор в файле нужно в начало переводить перед новым чтением. пробелы или слова не важно, главное результат.
З.Ы. складывается впечетление что сам не очень то и понимаешь что подсказываешь, плохой у Вас форум, не успел зарегиться как сразу обижать стали blink.gif да и злые Вы все... но всёравно спасибо З.Ы.Ы. твой вариант ВООБЩЕ не работал

Сообщение отредактировано: Vlad - 21.05.2009 19:11
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 22.05.2009 15:08
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Понимаеш, считать пробелы немного безграмотно,потому что если человек случайно поставит 2 пробела подрят у тебя выдаст 2 слова,а это уже ошибка.во вторых а почему ты не хочеш считывать и выводить на экран при первом же проходе.Зачем тебе 2 раза полностью проходить файл,или тебе ресурсы своего компутера девать некуда.насчет того что мой вариант не работает,вполне возможно, потому что набивал я прямо на форему без паскаля под рукой,но на что тебе голова,что подправить.И если уж тебе хочется выводить на экран,то получи,твою же прогу менял. кстати о птичках зачем весь файл собирать в строку,если ты в цикле можеш каждую букву отдельно печатать и на одну переменную меньше будет.
Код

uses crt;
var
fin: text;
ch:char;
s:integer;

begin
S:=0;
clrscr;
assign (fin,'D:\instal\PASCAL_7\tp7\prog\test.txt');
reset (fin);
while not eof(fin) do begin
read(fin,ch);
if ch = ' ' then
S:=S+1;
write(сh);
end;
close(fin);
write(S+1);
readln;
end.
Вот немного оптимизированный ТВОЙ вариант,но на мой взгляд тут можно столько ошибок наштамповать.Еще я немного сомневаюсь со значениями №10 и №13 для ch либо он просто ьудет выводить то что я написал,либо совершать нужное действие.

З,Ы Форум не плохой,просто сидеть и писать за всех код никто не будет.Тут могут дать только общие советы и критику твоего кода.Это я уж тут от ожидания ответа на свой вопрос начал писать код.Плюс,как я понял ваше задание,так вам и ответил,и если я сделал не совсем правильный результат(не выводил файл на экран),то это ваша вина в том что неправильно обьяснили.(Я от Volvo сам уже пару раз получил за это)насчет того что мы злые,.......да я очень злой и страшный серый волк,я в юных прогерах знаю толк...

Сообщение отредактировано: Krjuger - 22.05.2009 15:15
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Гость
сообщение 23.05.2009 15:29
Сообщение #15


Гость






Цитата
твой вариант ВООБЩЕ не работал

согласен! blum.gif
Krjuger, там ты не считывал с самого сначала ch, а потом после прохода цикла в файле небыло перехода на следующий символ. nea.gif

меня заинтересовал вариант с рекурсией - можешь пожалуйста написать эту процедуру? спс.
 К началу страницы 
+ Ответить 
Krjuger
сообщение 23.05.2009 16:00
Сообщение #16


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Гость слишком много слов можно было просто сказать,что я забыл перед циклом написать Reset(fin);
Что bменно тебя заинтересовало?Как рекурсивно проходить пробелы и весь ненужный мусор чтоли?
Код

Procedure probel;
begin
read(fin,ch);
if ch=' ' then{здесь конекретно пробел,а можно и все что тебе не нужно}
probel'
end;

либо
Код

Procedure probel;
begin
if ch=' ' then{здесь конекретно пробел,а можно и все что тебе не нужно}
begin
  read(fin,ch);
  probel'
end;
end;
То какую сделать зависит от того места куда вы холите вставить эту процедуру.проблема первой в данном исполнении заключается в том,что мы будем после удаления вех пробелов в ch иметь первый элемент нашего слова,и выйда из пробела мы уже считываем второй в цикле,в данной программе проблем это не должно создать,но могут быть случаи,когда это вызовет проблемы.

или вы имели в виду рекурсивную реализацию самой задачи?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
sheka
сообщение 23.05.2009 16:51
Сообщение #17


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
Код

program lab_file;

uses crt;
var
fin: text;
ch:char;
s:integer;

begin
assign (fin,'C:\Tpascal\test.txt');{как пример}
reset (fin);
while not eof(fin) do begin
while ch <> ' ' do
read(fin,ch);
S:=S+1;
end;
writeln(s);
end.


смотри:
во-первых, ch перед 1-м входом не инициализирована, что иногда вызывает ошибки.
во-вторых, допустим мы наткнулись на пробел, то есть ch:=""; S:=S+1; заходим на следующий повтор цикла:
while not eof(fin) do begin //допустим не конец файла
while ch <> ' ' do // вот здесь ошибка - ch="", и read(fin,ch); не выполняется, программа зацикливается.

спс за рекурсию good.gif , я с ней не очень дружу. а что, всю программу тоде модно было сделать рекурсией?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 24.05.2009 0:26
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Цитата

while ch <> ' ' do // вот здесь ошибка - ch="", и read(fin,ch); не выполняется, программа зацикливается.
Вообще то выполняется,потому что пустой элемент выполняет условие цикла и ТОЛЬко пробел обеспечивает нам вылет из цикла,насчет того что я в начале,не задаю значение ch,да туда запишется всякий мусор из памяти,и принципи там чисто теоретически может затесаться пробел,но шанс этого мал,принципи согласен лучше инициализировать ch.Это лиш увеличит стабильность.

Procedure rek;
begin
if not eod(fin) then
begin
if (ch <> ' ') then
begin
read(fin,ch);
rek;
end;
else
begin
S:=S+1;
read(fin,ch);
rek;
end;
end;
end;


Принципи оно должно сработать,на данный момент паскаля под рукой не имею,поэтому работоспособность проверить не могу,если где то ошибся,то сообщи исправлю.
И еще По сути любой цыкл можно заменить рекурсией, а рекурсию циклом,но есть моменты,когда это делать принципи нерационально.Вот например метод с циклом на мой взгляд в этой задаче проще,чем рекурсивный.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
sheka
сообщение 24.05.2009 11:51
Сообщение #19


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
Вообще то выполняется

если пробел - не выполняется read(fin,ch); посчитай сам!

вот отлаженые программы 2 способов (для файлов у которых первая и последняя буква не пробел, слова разделены 1 пробелом):

без рекурсии:
Код
var
  fin: text;
  ch:char;
  s:integer;

begin
s:=0;
assign (fin,'test.txt');
reset (fin);
while not eof(fin) do begin
  read(fin,ch);
  while (ch <> ' ')and(not eof(fin)) do read(fin,ch);
  S:=S+1;
  end;
close(fin);
end.


с рекурсией:
Код

var
  fin: text;
  ch:char;
  s:integer;

Procedure rek;
begin
while not eof(fin) do
  begin
  read(fin,ch);
   if (ch <> ' ')then rek
   else
     begin
       S:=S+1;
       rek;
     end;
  end;
end;

begin
s:=1;
assign (fin,'test.txt');
reset (fin);
rek;
close(fin);
end.


но я вчера сделал кому-то задачу, и там использовал
Цитата
Код
Procedure probel;
begin
if ch=' ' then{здесь конекретно пробел,а можно и все что тебе не нужно}
begin
  read(fin,ch);
  probel'
end;
end;
.

это самый оптимальный способ - и короткий, и для любого in-файла.

P.S то есть рекурсия используется как goto, но только на начало данной процедуры?
возникают ли с ней такие же глюки как и с goto?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 24.05.2009 12:12
Сообщение #20


Гость






Цитата
возникают ли с ней такие же глюки как и с goto?
Интересно, а какие глюки возникают с Goto? Ничего про глюки (при правильном использовании, а не втыкании куда надо и куда не надо, как и рекурсии, собственно), не слышал. Можно озвучить?

Только сразу говорю: без HolyWar-ов и догматичных утверждений о том, что goto - это плохо.
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 8.08.2025 4:53
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"