Что нового

Вывод в строки элементов массива, длина каждой строки не более N.

inx

Знающий
Сообщения
43
Репутация
12
Потребовалось получить из массива строки из его элементов, разделенных запятой, длина каждой строки не больше $SMaxLength (учитывать текущую длину строки + разделитель + длину следующего элемента который будет дописан). Вывод в Edit.
Если сам элемент уже длиннее N (=20 возьмем), то выводится одной строкой.
Возникли сложности с проверкой длины каждой строки.

Сейчас пытаюсь сделать как-то так, что не совсем работает. Направьте в нужном направлении :smile:

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Edit1 = GUICtrlCreateEdit("", 8, 8, 593, 417)
GUICtrlSetData(-1, "")
GUISetState(@SW_SHOW)

Dim $InputData[11] = ["55555", "88888888", "22", "333", "4444", "999999999", "7777777", "666666", "1", "одинадцать!", "четырнадцать!!"]
Global $SMaxLength = 20, $SLength, $SNextLength, $ArrayNextElementLength, $text = ""

	For $i = 1 To Ubound($InputData) - 1
		$ArrayNextElementLength = StringLen($InputData[$i])
		$SLength = StringLen($text)
		$SNextLength = $SLength + $ArrayNextElementLength + 1
		If $SNextLength <= $SMaxLength Then
			$text &= $InputData[$i] & ","
			_GUICtrlEdit_AppendText($Edit1, $InputData[$i] & ",")
		Else
			_GUICtrlEdit_AppendText($Edit1, "        Длина следующей строки была бы " & $SNextLength & ", поэтому пишем в новую." & @CRLF)
			_GUICtrlEdit_AppendText($Edit1, $InputData[$i] & ",")
			$text = ""
		EndIf
	Next

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit

	EndSwitch
WEnd
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Так?
Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Edit1 = GUICtrlCreateEdit("", 8, 8, 593, 417)
GUICtrlSetData(-1, "")
GUISetState(@SW_SHOW)

Dim $InputData[11] = ["55555", "88888888", "22", "333", "4444", "999999999", "7777777", "666666", "1", "одинадцать!", "четырнадцать!!"]
Global $SMaxLength = 20, $SLength, $SNextLength, $ArrayNextElementLength, $text = ""

    For $i = 0 To Ubound($InputData) - 1
        $ArrayNextElementLength = StringLen($InputData[$i])
        $SLength = StringLen($text)
        $SNextLength = $SLength + $ArrayNextElementLength + 1
        If ($SNextLength-1) <= $SMaxLength Then
            $text &= $InputData[$i] & ","
            _GUICtrlEdit_AppendText($Edit1, $InputData[$i] & ",")
        Else
            _GUICtrlEdit_AppendText($Edit1, "        Длина следующей строки была бы " & ($SNextLength-1) & ", поэтому пишем в новую." & @CRLF)
            _GUICtrlEdit_AppendText($Edit1, $InputData[$i] & ",")
            $text = $InputData[$i] & ','
        EndIf
    Next

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
ИМХО, так проще.
Код:
#include <GUIConstantsEx.au3>

Global $aInputData[12] = ['55555', '88888888', '22', '333', '4444', '999999999', '7777777', '666666', '1', 'одинадцать!', 'четырнадцать!!', _
		'2222222222222222222222'], $iMax = 20, $sData, $sDelim = ',', $iTmp

For $i = 0 To UBound($aInputData) - 1
	$iTmp = StringLen($aInputData[$i])
	If $iTmp > $iMax Then $iMax = $iTmp
	$sData &= $aInputData[$i] & $sDelim
Next
$iTmp = 0
$aInputData = StringRegExp($sData, '.{1,' & $iMax - StringLen($sDelim) & '}' & $sDelim, 3)
$sData = ''
For $i = 0 To UBound($aInputData) - 1
	$sData &= $aInputData[$i] & @CRLF
Next
$aInputData = 0
GUICreate('$iMax = ' & $iMax, 615, 438, 192, 124)
$nEdit = GUICtrlCreateEdit(StringTrimRight($sData, 2), 8, 8, 593, 417)
$sData = ''
GUICtrlSetState(GUICtrlCreateLabel('', 0, 0, 1, 1), $GUI_FOCUS)
GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
2 madmasles
Так не будет работать:

Код:
#include <GUIConstantsEx.au3>
#include <array.au3>
;                          !!!!!!!!!!!!!!!!!!!!!!!!!
Global $aInputData[12] = ['1234567890123456789012345', '88888888', '22', '333', '4444', '999999999', '7777777', '666666', '1', 'одинадцать!', 'четырнадцать!!', _
        '2222222222222222222222'], $iMax = 20, $sData, $sDelim = ',', $iTmp

For $i = 0 To UBound($aInputData) - 1
    $iTmp = StringLen($aInputData[$i])
    If $iTmp > $iMax Then $iMax = $iTmp
    $sData &= $aInputData[$i] & $sDelim
Next
$iTmp = 0
$aInputData = StringRegExp($sData, '.{1,' & $iMax - StringLen($sDelim) & '}' & $sDelim, 3)
_ArrayDisplay($aInputData)
$sData = ''
For $i = 0 To UBound($aInputData) - 1
    $sData &= $aInputData[$i] & @CRLF
Next
$aInputData = 0
GUICreate('$iMax = ' & $iMax, 615, 438, 192, 124)
$nEdit = GUICtrlCreateEdit(StringTrimRight($sData, 2), 8, 8, 593, 417)
$sData = ''
GUICtrlSetState(GUICtrlCreateLabel('', 0, 0, 1, 1), $GUI_FOCUS)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
madmasles
В случае если первый элемент $aInputData будет длиннее 20 символов переменной $iMax присваивается "большее" значение. Вследствие строка "$aInputData = StringRegExp($sData, '.{1,' & $iMax - StringLen($sDelim) & '}' & $sDelim, 3)" возвратит более длинную последовательность чем изначальное 20. Короче после того как "затираете" $iMax длина строки уже будет большей.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Z_Lenar [?]
В случае если первый элемент $aInputData будет длиннее 20 символов переменной $iMax присваивается "большее" значение.
Это сделано для того, чтобы все элементы массива $aInputData попали в Edit. Если нужно, чтобы в Edit попали не все элементы массива $aInputData, а только нужной длины, то можно сделать так.
Код:
#include <GUIConstantsEx.au3>

Global $aInputData[12] = ['1234567890123456789012345', '88888888', '22', '333', '4444', '999999999', '7777777', '666666', '1', 'одинадцать!', 'четырнадцать!!', _
		'2222222222222222222222'], $iMax = 20, $sData, $sDelim = ','

For $i = 0 To UBound($aInputData) - 1
	If StringLen($aInputData[$i]) > $iMax - StringLen($sDelim) Then
		ContinueLoop
	EndIf
	$sData &= $aInputData[$i] & $sDelim
Next
$aInputData = StringRegExp($sData, '.{1,' & $iMax - StringLen($sDelim) & '}' & $sDelim, 3)
$sData = ''
For $i = 0 To UBound($aInputData) - 1
	$sData &= $aInputData[$i] & @CRLF
Next
$aInputData = 0
GUICreate('$iMax = ' & $iMax, 615, 438, 192, 124)
$nEdit = GUICtrlCreateEdit(StringTrimRight($sData, 2), 8, 8, 593, 417)
$sData = ''
GUICtrlSetState(GUICtrlCreateLabel('', 0, 0, 1, 1), $GUI_FOCUS)
GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Если уж на то пошло... :smile:
Вот так вроде работает:

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include <Array.au3>

Global $aInputData[12] = ['1234567890123456789012345', '88888888', '22', '333', '4444', '999999999', '7777777', '666666', '1', 'одинадцать!', 'четырнадцать!!', _
        '2222222222222222222222'], $iMax = 20, $sStr, $sDelim = ',', $aData[1]

$sStr = _ArrayToString($aInputData, $sDelim) & $sDelim

$aData = StringRegExp($sStr, '((.*?).{1,' & $iMax & '}' & $sDelim & ')', 3)
GUICreate('$iMax = ' & $iMax, 615, 438, 192, 124)
$nEdit = GUICtrlCreateEdit('', 8, 8, 593, 417)
GUICtrlSetState(GUICtrlCreateLabel('', 0, 0, 1, 1), $GUI_FOCUS)
GUISetState()

For $i = 0 To UBound($aData)/2-1
	_GUICtrlEdit_AppendText($nEdit, $aData[$i*2] & @CRLF)
Next

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd


Длинные строки не обрезает.
 
Автор
I

inx

Знающий
Сообщения
43
Репутация
12
Если сам элемент уже длиннее N (=20 возьмем), то выводится одной строкой. (дополнил в первое сообщение темы)

Проверьте оба варианта например на:
Код:
Dim $InputData[16] = ["aaaaaaaaaaaaaaaaaaaaaa25", "bbbb5", "cccccc7", "dddddddd9", "ee3", "fffff6", "ggggggggg11", "hhhhhhhh10", "iiiiiiiiiiii14", "jjj4", "kkkkkkkkkkkkkkkkkkk21", "llll5", "mmmmmmmmmmmmmm16", "nnn4", "ppppppp8", "rrrr5"]


Элементы все выводятся, но во втором случае строки не соответствуют условию.

P.S. Пока писал, появился еще вариант от Z_Lenar, в нем тоже все работает.
 
Автор
I

inx

Знающий
Сообщения
43
Репутация
12
Не силен в регулярных выражениях, как можно в поcледнем варианте учесть другие виды разделителей? Замена $sDelim = ',' на '.' например все ломает.

Код:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include <Array.au3>

Global $aInputData[12] = ['1234567890123456789012345', '88888888', '22', '333', '4444', '999999999', '7777777', '666666', '1', 'одинадцать!', 'четырнадцать!!', _
        '2222222222222222222222'], $iMax = 20, $sStr, $sDelim = ',', $aData[1]

$sStr = _ArrayToString($aInputData, $sDelim) & $sDelim

$aData = StringRegExp($sStr, '((.*?).{1,' & $iMax & '}' & $sDelim & ')', 3)
GUICreate('$iMax = ' & $iMax, 615, 438, 192, 124)
$nEdit = GUICtrlCreateEdit('', 8, 8, 593, 417)
GUICtrlSetState(GUICtrlCreateLabel('', 0, 0, 1, 1), $GUI_FOCUS)
GUISetState()

For $i = 0 To UBound($aData)/2-1
    _GUICtrlEdit_AppendText($nEdit, $aData[$i*2] & @CRLF)
Next

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
inx
Код:
$aData = StringRegExp($sStr, '((.*?).{1,' & $iMax & '}' & $sDelim & ')', 3)

Исправь на
Код:
$aData = StringRegExp($sStr, '((.*?).{1,' & $iMax & '}' & '\' & $sDelim & ')', 3)
 
Верх