Помощь - Поиск - Пользователи - Календарь
Полная версия: неправильная работа со строками в TP 7
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Altair
напишем программу:

Код
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
Строка в Паскале - не только набор символов в массиве, но еще и длина этого набора. Длина хранится в нулевом элементе массива. В этои примере она остается неизменной и равной нулю.
APAL
Правильнее будет так:

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

>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
Лучший способ ввести посимвольно строку:
Код
const n = 10;
...
For b:=1 to n do begin write('s[',b,']='); readln(s[b]); S[0]:=CHR(B) end;
...

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

Также можно попробовать вместо  S[0]:=CHR(B) поставить inc(s[0]) - может, чуть быстрее будет...
GLuk
По-моему лучше юзать ASCIIZ строки (модуль Strings) ;)
SKVOZNJAK
Круто он всех подколол! А заменить поэтапно операторы на альтернативные никто не догадался ;)
Код

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

А вот что меня си-и-ильно удивило (спасибо за классный тест smile.gif), так это то, что в таком случае работает и оператор WriteLn. Кто-нибудь, скажите мне, какого ... он работает! (В опциях компилятора отключен Extended syntax, про который я сначала подумал)
Altair
ОПЕРАЦИЯ ПРИСВАИВАНИЯ РАБОТАЕТ!!!!!!!!

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

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

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

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

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

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