Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ обработка текста из внешнего текстового файла

Автор: футбик 22.10.2008 17:16

полное описание: Выполнить обработку текста из внешнего текстового файла, созданного в редакторе . Результаты обработки поместить во внешний файл. Определить количество строк в исходном тексте. Проверить имеется ли в каждой строке баланс.
количество строк определил так:

var oldf,newf:text;
oldn,newn:string;
s:integer;
begin
writeln('Введите имя файла');
readln(oldn);
writeln('Введите новое имя');
readln(newn);
assign(oldf,oldn);
assign(newf,newn);
reset(oldf);
rewrite(newf);
s:=1; {это смущает}
while not eof(oldf) do
begin
readln(oldf);
begin
s:=s+1;
end;
end;
writeln(newf,'строк: ',s);
close(newf)
end.


кто знает, подскажите пожалуйста, что означает: проверить имеется ли в каждой строке баланс.

Автор: volvo 22.10.2008 18:19

Цитата
что означает: проверить имеется ли в каждой строке баланс.
Почему-то есть ощущение, что это не полное предложение... Баланс не может быть сам по себе, должен быть баланс чего-то (открытых/закрытых скобок, например)... Уточни задание у того, кто его тебе дал.

Автор: футбик 26.10.2008 20:34

в задании была ошибка, нужно проверить баланс скобок, будем разбираться что это означает rolleyes.gif

Автор: мисс_граффити 27.10.2008 3:54

Это значит, что каждой открывающейся скобке поставлена в соответствие закрывающаяся.
Поищи по форуму, такое решалось неоднократно

Автор: футбик 27.10.2008 22:12

всегда выводит 'баланс не нарушен', подскажите пожалуйста в чем дело

var oldf,newf:text;{Файловые пеpеменные для
стаpого и нового файлов}
oldn,newn:string;{Стpоковые пеpеменные, для хранения
имен нового и стаpого файлов}
bal:string;
i,s:integer;
a:integer;
begin
writeln('Введите имя файла');
readln(oldn);
writeln('Введите новое имя');
readln(newn);
assign(oldf,oldn);
assign(newf,newn);
reset(oldf); {Откpыть стаpый файл по чтению}
rewrite(newf); {Откpыть новый файл по записи}
s:=1;
a:=0;
while not eof(oldf) do
begin
readln(oldf);{Читаем стpоку из стаpого файла}
begin
s:=s+1;
end;
for i:=1 to length(bal) do
if bal[i]='(' then inc(a);
if bal[i]=')' then dec(a);
end;
if a=0 then writeln('баланс не нарушен')
else writeln('баланс нарушен');
writeln(newf,'строк: ',s);
close(newf)
end.


Автор: volvo 27.10.2008 22:28

Во-первых, уточняй, вот это должно признаться как существование баланса, или нет:
)(())(
? Вроде бы количество открытых и закрытых скобок совпадает, но речи о правильной вложенности нет...

Во-вторых:

       readln(oldf, bal); { <--- Раз: читать надо строку из файла }
...
for i:=1 to length(bal) do
BEGIN { <--- Два }
if bal[i]='(' then inc(a);
if bal[i]=')' then dec(a);
END; { <--- Три }
Если нужно контролировать еще и вложенность, то во втором условии (при проверке на закрывающуюся скобку) надо смотреть, а есть ли открытые, то есть, A > 0 или нет...

Автор: футбик 28.10.2008 0:11

все понял, еще раз спасибо smile.gif

Автор: футбик 29.10.2008 17:41

еще маленький вопросик по файлам, делаю программу, она преобразует текстовый файл в типизированный, элементы которого - вектора из 8 –и чисел типа Integer. Текстовый файл содержит 5 строк по 8 чисел в строке, числа выбирается из интервала [ 0,100] . Не получается преобразовать текст. файл в типиз. blink.gif
код

var f:text;
newf: file of integer;
el:string;
a:array[1..5,1..8] of integer;
i,j:integer;
begin
assign(f,'C:\PABCWork\p1.txt');
reset(f); {Откpыть стаpый файл по чтению}
assign(newf,'C:\PABCWork\p2.txt');
rewrite(newf); {Откpыть новый файл по записи}
while not eof(f) do
begin
readln(f,el);
for i:=1 to 5 do {просто хочу прочитать текстовый и перезаписать в типиз.файл}
begin
for j:=1 to 8 do
write(newf,a[i,j]); { на выходе типиз. файл пустой }
writeln;
end;
end;
close(newf)
end.

исходный, текстовый файл сделал так:
var f:text;
a:array[1..5,1..8] of integer;
i,j:integer;
begin
assign(f,'C:\PABCWork\p1.txt'); {Откpыть стаpый файл по чтению}
rewrite(f); {Откpыть новый файл по записи}
for i:=1 to 5 do
for j:=1 to 8 do a[i,j]:=random(100);
for i:=1 to 5 do
begin
for j:=1 to 8 do
write(f,a[i,j]);
writeln;
end;
close(f);
end.

заранее благодарен

Автор: volvo 29.10.2008 18:11

Цитата
{ на выходе типиз. файл пустой }
Неправда... То, что он содержит Нули (символ NUL, с кодом = 0) - не значит, что он пустой... На размер файла посмотри.

Цитата
Текстовый файл содержит 5 строк по 8 чисел в строке
Опять неправда... Текстовый файл содержит все числа, записанные одно после другого, даже не разделенные пробелами (ты пробелы в текстовый файл не записывал, поэтому не удивляйся, что их там нет), и в одну строку (да, опять не удивляйся, writeln и writeln(f) - это совсем разные вещи)...

Если сделать в первой программе так:
for i:=1 to 5 do
begin
for j:=1 to 8 do
write(f,a[i,j], ' ');
writeln(f);
end;
, то будет то, чего ты ждешь: числа, разделенные пробелами, по 8 штук в строке.

Теперь по перезаписи в типизированный файл. Вот этого:
var x: integer;
...
while not eof(f) do
begin
for j:=1 to 8 do begin
read(f, X);
write(newf,X);
end;
readln(f); { <--- Переводим строку в текстовом файле }
end;

вполне достаточно. Чтобы не быть привязанным к числу столбцов, можно воспользоваться While not eoln(f) do вместо того For-а, который остался...

Автор: футбик 29.10.2008 23:05

а почему типизированый файл выдает: '^ L c I M ...', там же должны быть цифры rolleyes.gif ?

begin
assign(f,'C:\PABCWork\p1.txt');
reset(f);
assign(newf,'C:\PABCWork\p2.txt');
rewrite(newf);
while not eof(f) do
begin
While not eoln(f) do
begin
read(f, x);
write(newf,x);
end;
readln(f);
end;
close(newf)
end.

спасибо

Автор: volvo 29.10.2008 23:21

Цитата
там же должны быть цифры
Цифры у тебя были в текстовом файле... В типизированнои информация хранится без перевода в понятную тебе форму, прямо так, как она понятна компьютеру... То есть, просто берется содержимое ячейки памяти, и пишется в файл. Если ты потом открываешь этот файл текстовым редактором - то это твоя ошибка, файл НЕтекстовый, несмотря на расширение, и чтобы просмотреть его, надо либо написать еще одну программу, которая будет читать данные из файла, и показывать их тебе WriteLn-ом (то есть, опять же, переводя это в текстовую форму, удобную тебе), или каким-нибудь Hex-редактором, он покажет тебе содержимое файла "как оно есть", правда в 16-ричной СС...

Автор: футбик 30.10.2008 0:37

огромное спаибо за предоставленую информацию smile.gif

Автор: футбик 2.11.2008 22:34

помогите пожалуйста еще с файлами, есть проблемка. Нужно разделить все элементы вектора типизированного файла на максимальный элемент, и поместить результат в типиз. файл.

var
newf: file of real;
oldf: file of integer;
a:array[1..5,1..8] of integer;
b:array[1..5,1..8] of real;
i,j:integer;
amax:real;
begin
assign(oldf,'C:\PABCWork\p2.txt');
reset(oldf);
assign(newf,'C:\PABCWork\p3.txt');
rewrite(newf);
while not eof(oldf) do
begin
for i:=1 to 5 do
for j:=1 to 8 do
begin
read(oldf,a[i,j]);
for i:=1 to 5 do //перебираю строки
begin
amax := a[i,1]; //1й элемент в каждой строке максимальный
for j:=2 to 8 do //перебираю столбцы, с 2го
begin
if a[i,j]>amax then amax:=a[i,j];//сравниваю 1й элемент строки с остальными и присваиваю значение amax = максимальное
end;
for j:=1 to 8 do
begin
if amax<>0 then b[i,j]:=(a[i,j]/amax); //делю каждый элемент строки на макс. значение этой строки
end;
end;
end;
end;
for i:=1 to 5 do
begin
for j:=1 to 8 do
write(newf,b[i,j]);
end;
close(newf);
end.

работает не правильно:
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
читаю результат так:
var f:file of real;
newf:text;
x:integer;
a:array[1..5,1..8] of real;
i,j:integer;
begin
assign(f,'C:\PABCWork\p3.txt');
reset(f); {Откpыть стаpый файл по чтению}
assign(newf,'C:\PABCWork\p4.txt');
rewrite(newf); {Откpыть новый файл по записи}
while not eof(f) do
begin
for i:=1 to 5 do
begin
for j:=1 to 8 do
read(f,a[i,j]);
for j:=1 to 8 do
write(newf,a[i,j],' ');
writeln(newf);
end;
end;
close(newf)
end.


эта прога работает, проверял. Спасибо

Автор: volvo 2.11.2008 23:21

Цитата
работает не правильно:
Естественно... Смотри, что ты делаешь:

Цитата
// зачем тебе цикл while not eof, ты ж используешь точную
// размерность массива ?
while not eof(oldf) do
begin
for i:=1 to 5 do
for j:=1 to 8 do
begin
read(oldf,a[i,j]); // <--- Внимание! Прочитал один элемент, и уже перебираешь строки?
// Вот тут точно end не забыл ???

for i:=1 to 5 do //перебираю строки
begin
amax := a[i,1];
for j:=2 to 8 do
begin
if a[i,j]>amax then amax:=a[i,j];
end;
for j:=1 to 8 do
begin
if amax<>0 then b[i,j]:=(a[i,j]/amax);
end;
end;
end;
end;

На самом деле тебе даже не надо выделять память подо всю матрицу 5 * 8, достаточно описАть вектор из 8-ми integer-ов, и читать в него "построчно", правда для этого придется чуть-чуть переделать программу. И массив B не нужен. И даже вектор не нужен, достаточно вообще одной переменной типа Real, ты все равно делишь каждый элемент строки на максимум, вот сразу дели и записывай в файл...

Кстати, вопрос на засыпку: ты ничего не хочешь сделать, если максимум в строке = 0? Что тогда будет записываться в файл? Ты ж в этом случае не пишешь ничего в матрицу B...

P.S. Форматируй программы, таких ошибок будет меньше...

Автор: футбик 3.11.2008 14:21

работает . Контрольные по паскалю готовы, спасибо за помощь smile.gif