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

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

Форум «Всё о Паскале» _ Задачи _ неправильная работа со строками в TP 7

Автор: Altair 21.12.2003 11:26

напишем программу:

Код
var s : string[10];
     b : byte;
begin
for b :=1 to 10 do begin writeln('s[',b,']='); readln(s[b]) end;
{  это мы ввели посимвольно строку }

{ for b:=1 to 10 do s:=s+s[b];   }  {*******}

writeln('s=',s);  

{ ПОЧЕМУ СТРОКА НЕ ВЫВОДИТСЯ ? }
{ теперь раскоментируйте *******  и ВСЕ ПОЛУЧИТСЯ! }

end.


ПОЖАЛУЙСТА, ОБЪЯСНИТЕ ЭТО МНЕ, ЕСЛИ ЗНАЕТЕ! ??? ???

Автор: trminator 21.12.2003 16:08

Строка в Паскале - не только набор символов в массиве, но еще и длина этого набора. Длина хранится в нулевом элементе массива. В этои примере она остается неизменной и равной нулю.

Автор: APAL 23.12.2003 1:38

Правильнее будет так:

>напишем программу:
>

Код

>var s : string[10];
>      ch : Char;
>      b : byte;
>begin
>s:='';
>for b :=1 to 10 do begin write('s[',b,']= '); readln(Ch); {Или вместо readln - Ch:=Readkey} s:=s+ch; end;
>{  это мы ввели посимвольно строку }
>
>{ for b:=1 to 10 do s:=s+s[b];   }  {*******}
>
>writeln('s=',s);  
>
>{ ПОЧЕМУ СТРОКА НЕ ВЫВОДИТСЯ ? }
>{ теперь раскоментируйте *******  и ВСЕ ПОЛУЧИТСЯ! }
>
>end.

Автор: Altair 30.12.2003 10:51

Лучший способ ввести посимвольно строку:

Код
const n = 10;
...
For b:=1 to n do begin write('s[',b,']='); readln(s[b]); S[0]:=CHR(B) end;
...

таким образом мы с каждым новым символом, увеличиваем и длинну строки! 8)

Автор: trminator 30.12.2003 18:28

способ конечно хороший, но не совсем корректный, в Паскале такого не предусмотрено, значит, некоторые компиляторы могут выдавать ошибку. Я чесно говоря думал, что Турбо Паскаль будет ругаться.

Также можно попробовать вместо  S[0]:=CHR(B) поставить inc(s[0]) - может, чуть быстрее будет...

Автор: GLuk 31.12.2003 7:48

По-моему лучше юзать ASCIIZ строки (модуль Strings) ;)

Автор: SKVOZNJAK 1.01.2004 14:41

Круто он всех подколол! А заменить поэтапно операторы на альтернативные никто не догадался ;)

Код

uses crt;
var
s:   string[10];
R:   STRING;
Q,b: byte;
LABEL 1;
begin
FOR Q:=1 TO 20 DO IF KEYPRESSED=TRUE THEN READKEY;
WRITELN;
for b :=1 to 10 do begin
     writeLn('s[',b,']=');
     S[B]:=READKEY;
1: FOR Q:=1 TO 20 DO IF KEYPRESSED=TRUE THEN READKEY; DELAY(400);
IF KEYPRESSED=TRUE THEN GOTO 1;
     end; writeln('aaaaaaaa]]]GTRETRETREWOIKREWREWOPKREWOPKREWOPKREW]]]]]]]]'); writeln('s=',s); {А ВОТ НЕ БУДЕТ РАБОТАТЬ!}
WRITELN;
R:=S;            {ЭТО ТОЖЕ НЕ БУДЕТ!!!!!!}
WRITELN('ОПЕРАЦИЯ ПРИСВАИВАНИЯ НЕ РАБОТАЕТ','   ',R);
FOR Q:=1 TO 10 DO R[Q]:=S[Q];
WRITELN('А ВО ТЕПЕРЬ...','   ',R);
WRITE('R=');
FOR Q:=1 TO 10 DO WRITE(R[Q]);
WRITELN;
WRITE('Q=');
FOR Q:=1 TO 10 DO WRITE(S[Q]);
end.
ИТАК, МЫ ПОЛУЧИЛИ СТРОКУ СО СВОЙСТВАМИ МАССИВА. А НУЛЕВОЙ СИМВОЛ ЗДЕСЬ ВООДЩЕ НЕ ПРИЧЕМ.

Автор: trminator 1.01.2004 16:40

Мы получили не строку со свойствами массива, а массив символов. При этом потерялись все преимущества строки (знаем длину!), но не приобрелись никакие новые (не работает присваивание - видимо, из-за того, что у нас "строки" по-прежнему нулевой длины). С таким же успехом можно было описать тип TStr = array[1..10] of char а наши строки описать как TStr. Тогда, кстати, заработает присваивание.

А вот что меня си-и-ильно удивило (спасибо за классный тест smile.gif), так это то, что в таком случае работает и оператор WriteLn. Кто-нибудь, скажите мне, какого ... он работает! (В опциях компилятора отключен Extended syntax, про который я сначала подумал)

Автор: Altair 3.01.2004 15:07

ОПЕРАЦИЯ ПРИСВАИВАНИЯ РАБОТАЕТ!!!!!!!!

в строке R:=S; у нас происходит следующее:
строке R присваивается массив символов, где 0 символ это CHR(0)

кстати у меня не работает : WRITELN('А ВО ТЕПЕРЬ...','   ',R); ( R не печатается, и не должно печататься)
оператор writeln(s) или write(s) распечатает на экран столько символов, сколько сказанно в s[0]
(только там символ, а не число).

Автор: trminator 3.01.2004 15:47

Ты в отладчике проверял? Там ничего не присваивается, убедиться можно хотя бы поставив в watches не просто R, а R,M (Memory dump)

А все-таки, неужели он умеет печатать просто массивы символов?

Автор: GLuk 6.01.2004 20:35

2trminator: Вызов функции присваивания происходит, но цикл выполняется 0 раз. И, блин, первый раз вижу, что в паскале, строка, описанная как переменная - инициализируется нулем! Просто никогда до этого не использовал такой извращенный цикл присваивания, без модификации байта длины.
А что ты имел в виду под вопросом?:
А все-таки, неужели он умеет печатать просто массивы символов?

Автор: trminator 6.01.2004 21:02

Цитата
А что ты имел в виду под вопросом?

Я имел ввиду, например, следующий кусок кода:
Код

var a: array[1..10] of char;
   i: integer;
begin
   for i:=1 to 10 do readLn(a[i]);
   writeLn(a)
end.

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