Author Topic: Массивы: как с этим жить дальше?! [Нумератор строк]  (Read 2272 times)

0 Members and 1 Guest are viewing this topic.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Немножко порылся по функциям из тутора, встретил несколько изюминок при работе с массивами:

  • Количество строк функция TFCount возвращает неверно, а именно если последняя строка пустая, то она не считается, то есть в обычном пустом файле с нуля символами TFCount=0, а сразу как только добавляешь первый символ TFCount=1. Но этот недостаток с успехом компенсируется логикой функции TFWrite, которая хоть и добавляет в конец без спроса одну пустую строку (при отсутствии таковой), но зато не тупит в разных вариациях и действует как надо, так что минус на минус будет плюс.
  • Неожиданно ARRPOP извлекает элементы не из начала, а с конца массива. Yooooooooooooooooo! Почему так? как извлекать с начала? и как исправить порядок в массиве, отсортированном задом наперёд?! Так же неожиданно TFWriteArr не инвертирует порядок, так что с её помощью исправить ситуацию не получится.
  • Я так часто работаю с функцией фор, что при переборе элементов массива решил впихнуть в конец этого фора inc($i), что разумеется было лишним ввиду автоматической инкрементации переменной.
  • Захотелось поиграться изменением элементов массива в цикле на ходу. Накропал это:
    [spoiler=По идее, нумеровщик строк]
Code: (clickermann) [Select]
define($init) // одноразовый логклир
if ($init=0)
   logclear
   inc($init)
end_if

$numstr=TFCount("test.ini") // кол-во строк
print($numstr)

TFReadArr("test.ini", $arr )
$arse=arrSize($arr)
for($j, $j < $arse)
   $newel=strconcat($j+1," ",arrpop($arr))
   arrpush($arr, $newel)
   print( $arr[$j] )
end_cyc

TFWriteArr("stet.ini", $arr )

halt
    [/spoiler]

    Но вот интерпретатор мой так не думает и радует меня разными ошибками. Из исходного тестового файла с тремя заполненными строками в лог он выводит только две, при этом вторую портит (печатая вместо неё собачку), а результирующий файл пишет только одну портаченную строку вместо трёх. [/li]
  • Мож ещё ништяков надыбаю) Вот кстать на форуме спойлер сломался, не прячет инфу в себя, или мож я натупил с тегами бб гдет. Хотя не, скорее всего, это просто таков спойлер внутри списка.

ПС. Заменил аррпоп переменной, строки появились все, портачить их перестало, но номера в начале строки тож не проставило, зато все номера вывело в последнюю строку и.. в обратном порядке, классика.

[spoiler]
Code: (clickermann) [Select]
TFReadArr("..\data\test.ini", $arr )
$arse=arrSize($arr)
for($j, $j < $arse)
   $currt=arrpop($arr)
$newel=strconcat($j+1," ",$currt)
   arrpush($arr, $newel)
print( $arr[$j] )
end_cyc

Вход:
Code: [Select]
a111
b222
cd
Выход:
Code: [Select]
21:55:00 3
21:55:00 a111
21:55:00 b222
21:55:00 3 2 1 cd



И таблица в спойлере не работает, упс.
[/spoiler]

Плохой с меня изменяльщик массива, забью на этот ридэррей.   :)
« Last Edit: August 17, 2017, 10:09:55 PM by Cleoss »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Это всё от недопонимания.

Количество строк функция TFCount возвращает неверно, а именно если последняя строка пустая, то она не считается, то есть в обычном пустом файле с нуля символами TFCount=0, а сразу как только добавляешь первый символ TFCount=1. Но этот недостаток с успехом компенсируется логикой функции TFWrite, которая хоть и добавляет в конец без спроса одну пустую строку (при отсутствии таковой)...
Всё работает правильно, никаких мнимых 'недостатков' нет. Почитай что такое управляющие символы...
Пока в строке нет ни одного символа и строки нет, а как иначе?

Вот сколько здесь строк?
абракадабра\nвторая строка (подсказка)\n
ну хочешь так напишу
Quote
абракадабра\n
вторая строка (подсказка)\n

Здесь две строки. Если записать любой программой в файл, там тоже будет 2. И кликер покажет две.
А открой в редакторе... тоже две, но! в конце каждой строки есть управляющий символ \n - перевод строки.
Второй \n всё ещё во второй строке, хоть курсор уже стоит ниже, там где будет 3 строка. Но третьей ещё нет, пока там нет ни одного символа хоть отображаемого, хоть неотображаемого.

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


2.А как должно быть? Общий стандарт или правило, память заполняется от начала к концу от меньших адресов к большим. Соответственно в структуре размер которой ты не знаешь изначально (у нас же динамические массивы) дописываются новые элементы в конце.
push pop команды для работы поипринципу стека: последний вошел, первый вышел.
В языках конечно бывают и массивы с методами работы по принципу очереди: первый вошел - первый вышел. И смешанные типы. И т.д. и т.п. У нас пока только такой.
Всё упирается в оптимизацию скорости и памяти. Этот самый простой.

3. no comment

4.не интерпритатор самодур, а код неправильный. Не в написании, а логика неправильна.
Ты открываешь шкаф, на тебя выпадает крайняя футболка, ты пишешь на ней номер '1' запихиваешь назад с краю и закрываешь.
Открываешь опять и падает та же футболка. Ты перед 1 дописываешь 2 и запихиваешь назад и так много раз.

Вопрос, по окончании, ты пронумеровал все вещи в шкафу?


Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
ВотЪ подправил:
[spoiler]
Code: [Select]
TFReadArr("..\data\test.ini", $arr )
$arse=arrSize($arr)
for($j, $j < $arse)
//   $currt=arrpop($arr)
   $currt=$arr[$j]
   $k=$j+1
$newel=strconcat($k," ",$currt)
   arrpush($arr2, $newel)
print($j+1," ",$arr[$j])
end_cyc
[/spoiler]

Только теперь трабл: нумерация строк 1 2 3, а не 01, 02, 03. Нужны поверки или как-то округлением можно обойти?

Ещё прикол: TFWRITEARR очищает весь файл перед записью в него (недокументированная способность))ю
« Last Edit: August 17, 2017, 11:38:48 PM by Cleoss »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
если тебе просто нужно пронумеровать строки, массивы это лишнее. можно на прямую перебирать текстовый файл .
Code: (clickermann) [Select]
FOR($a=1,$a<TFCOUNT ("test.txt")+1)
   IF($a < 10)
      TFWRITE ("test_out.txt",STRCONCAT ("0",$a,". ",TFREAD ("test.txt", $a)), $a)//если меньше десяти, добавляем "0"
   else
      TFWRITE ("test_out.txt",STRCONCAT ($a,". ",TFREAD ("test.txt", $a)), $a)
   END_IF
END_CYC
halt

если так уже чешется, то можно и через массив, итог тот-же.
Code: (clickermann) [Select]
TFReadArr("test.txt", $arr )

FOR($a=0,$a<ARRSIZE($arr))
   IF($a < 9)
      $arr[$a]= STRCONCAT ("0",$a+1,". ",$arr[$a])
   else
      $arr[$a]= STRCONCAT ($a+1,". ",$arr[$a])
   END_IF
END_CYC

TFWRITEARR ("test_out.txt", $arr)
halt

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Quote from: Vint
Вот сколько здесь строк?
Я завёлся из-за т. ч. мой НП++ показывает на один символ больше постоянно) Но мысль я понял.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
если тебе просто нужно пронумеровать строки, массивы это лишнее. можно на прямую перебирать текстовый файл .
Code: (clickermann) [Select]
   IF($a < 10)
      TFWRITE ("test_out.txt",STRCONCAT ("0",$a,". ",TFREAD ("test.txt", $a)), $a)//если меньше десяти, добавляем "0"
   else
      TFWRITE ("test_out.txt",STRCONCAT ($a,". ",TFREAD ("test.txt", $a)), $a)
   END_IF

Во, я только подумал о проверках, а ты уже написал вариант, спасиб, Драмчег! 

Не то, что бы так сильно нужно, просто баловался разными функциями и понял, что у меня случайно вышел нумератор.. который работает.. наполовину)) 
А ваще искал, чем записать часть одного файла в конец другого и по ходу перебирал подходящие функции, и вот TFWriteArr отпал, поскольку он перезаписывает, а не дополняет, без вариантов.

Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Пытался на основе вышепредставленного кода написать автосохранялку для const.txt:

[spoiler]
Code: (clickermann) [Select]
define($init)
if ($init=0)
   logclear
   inc($init)
end_if

$f1="..\data\test.ini"
$f2="..\data\stet.ini"
$numstr=TFCount($f1)
print($numstr)
$nums=(TFCount($f2))
print($nums)

$frst = TFREAD ($f2, 1)
print("First line: ",$frst)
$bgn = strcut($frst,1,3)
print("First symz: ",$bgn)
$sttz="//#"

if($bgn ! $sttz)

$posit=4
$diffrc=$numstr+1-$posit
FOR($a=$posit,$a<$numstr+1)
             $ln=TFREAD ($f1, $a)
TFWRITE ($f2,$ln)
  print($ln)
END_CYC

$setd=strconcat("//#",$nums,"- Не изменяйте и не смещайте эту первую строку! ")
TFWRITE ($f2,$setd,1)

hintpopup("Настройки const.txt произведены! ","CLMN Settings")

else

hintpopup("Настройки const.txt уже внесены! ","CLMN Settings")

end_if

halt
[/spoiler]

Но интерпретатор почему-то выдаёт ошибку на строке if($bgn ! $sttz)  :(

errorlog.txt:
Code: [Select]
18.08.2017 11:44:47 Thread _MAIN(0) raise exception