Page 1 of 3

Counting Items in the DataSection?

Posted: Fri May 02, 2025 5:42 pm
by EaxVal
Hello,
Is there a function can count the Fruits in the "DataSection"?
Thank you in advance.

Code: Select all

Procedure CountFruits()
  Count = 0               ; Count the number of "Data.s" in the DataSection
  While NextData()        ; Read until end of data section (I know, NextData is not exist in PB)
    Count + 1
    NextData()
  Wend
EndProcedure

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
EndDataSection

CountFruits()
Debug Count

Re: Counting Items in the DataSection?

Posted: Fri May 02, 2025 6:01 pm
by Shardik
You may use an end marker like for example ETX (end of text):

Code: Select all

Procedure CountFruits()
  Count = 0
  Restore FruitList
  Repeat
    Read.S Fruit$

    If Fruit$ <> #ETX$
      Count + 1
    EndIf
  Until Fruit$ = #ETX$

  ProcedureReturn Count
EndProcedure

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
  Data.s #ETX$
EndDataSection

Debug CountFruits()

Re: Counting Items in the DataSection?

Posted: Fri May 02, 2025 6:23 pm
by EaxVal
Thank you Addict, but i want my DataSection stay clean without any additives like #ETX$

Re: Counting Items in the DataSection?

Posted: Fri May 02, 2025 7:17 pm
by benubi
Just add an empty "sentinel value" then, and check for #Empty$ instead of #ETX$. Add an empty string element or a word value set to 0 (Data.w 0)

You could also insert an integer value before the fruits that tells your reader procedure how many items there will be.

Re: Counting Items in the DataSection?

Posted: Fri May 02, 2025 9:10 pm
by mk-soft
I also use #ETX$. Thus, text with blank lines can also be read well.

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 2:06 am
by BarryG
EaxVal wrote: Fri May 02, 2025 6:23 pmi want my DataSection stay clean without any additives like #ETX$
You can't; you have to test for the end of data somehow. There's no command to do it as the compiler can't know when there's no more.

Why does your DataSection need to stay "clean" anyway? The user isn't going to see it when your app is running, and ending it with "Data.s #ETX$" on its own line is no big deal.

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 3:46 am
by RASHAD
Hi EaxVal
With string the only way is the what had posted by Shardik
Next is another approach maybe it will suit you :)

Code: Select all

items = (?FruitListend-?FruitList)/SizeOf(integer)

Restore FruitList

For i = 1 To items
  Read.i a
  Debug PeekS(a)
Next

DataSection
  FruitList:
  Data.i @"Apple", @"Orange"
  Data.i @"Mango", @"Mango"
  FruitListend:
EndDataSection

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 7:07 am
by Piero
WOW RASHAD!

PS: I wonder why anyone would need to count a "constant" at (final version) runtime…

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 10:09 am
by pjay
I'd keep it simple and add a count value directly:

Code: Select all

DataSection
  FruitList:
  Data.i 4 ; <<<<
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
EndDataSection

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 10:56 am
by Quin
pjay wrote: Sat May 03, 2025 10:09 am I'd keep it simple and add a count value directly:

Code: Select all

DataSection
  FruitList:
  Data.i 4 ; <<<<
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
EndDataSection
The reason I prefer to put something at the end of the data myself is so I don't have to manually keep increasing this number every time. It does work though :)

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 4:56 pm
by AZJIO
Make the data in a separate file and add it to Xincludefile. Start entering data from line 11, then you need to subtract 10 to get the number of lines. Click Ctrl+End to move to the end of the data. Look at the number of the last line in which the data is located, subtract 10 and get the number of lines.

In any case, whether you will look for the end of the data or check the “For” cycle counter, the energy spent will be the same.

Check #etx is performed once

Code: Select all

Procedure CountFruits()
	Count = 0
	Restore FruitList
	Repeat
		Read.s Fruit$
		If Asc(Fruit$) <> #ETX
			Count + 1
		Else
			Break
		EndIf
	ForEver
	ProcedureReturn Count
EndProcedure

DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Mango"
	Data.s #ETX$
EndDataSection

Debug CountFruits()
If you calculate the number of static (stiffly specified) data by transferring in the cycle, then you spend energy useless.
You can store the number of data in a new mark at the end of the data, so you will not have to scroll the code up/down

Re: Counting Items in the DataSection?

Posted: Sat May 03, 2025 5:35 pm
by RASHAD
Hi all
I got some time to play with string DataSection :D
1 :

Code: Select all

tByte = ?FruitListend-?FruitList

Restore FruitList

For no = 1 To 100
  Read.s txt$
  result = StringByteLength(txt$)+2
  chk = chk + result
  If chk = tByte
    Break
  EndIf
Next

Debug no

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
  Data.s "Mango", "Mango"
  Data.s "Apple", "Orange"
  FruitListend:
EndDataSection
2 : For the forum member who has bad feelings against Break

Code: Select all

tByte = ?FruitListend-?FruitList

Restore FruitList

Repeat
  Read.s txt$
  result = StringByteLength(txt$)+2
  chk = chk + result
  items + 1
Until chk = tByte

Debug items

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
  Data.s "Mango", "Mango"
  Data.s "Apple", "Orange"
  FruitListend:
EndDataSection

Re: Counting Items in the DataSection?

Posted: Sun May 04, 2025 4:21 am
by HobbyProgger

Code: Select all

*Read.string = @*Restore

*Restore = ?FruitList
Repeat
  *Restore + Len (*Read\s) * 2 + 2
  items + 1
Until *Restore = ?FruitListend

Debug items

DataSection
  FruitList:
  Data.s "Apple", "Orange"
  Data.s "Mango", "Mango"
  Data.s "Mango", "Mango"
  Data.s "Apple", "Orange"
  FruitListend:
EndDataSection
Here's my approach.

Re: Counting Items in the DataSection?

Posted: Sun May 04, 2025 6:21 am
by AZJIO

Code: Select all

EnableExplicit

Procedure CountData()
	Protected items, *c.Character
	*c = ?FruitList
	Repeat
		If *c\c = 0
			items + 1
		EndIf
		*c + SizeOf(Character)
	Until *c > ?FruitListend
	ProcedureReturn items
EndProcedure


Debug CountData()

DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Apricot"
	Data.s "Banana", "Pear"
	Data.s "Peach", "Tangerine"
	FruitListend:
EndDataSection
In a compiled program, the procedure is not needed.

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_Debugger
 
Procedure CountData()
	Protected items, *c.Character
	*c = ?FruitList
	Repeat
		If *c\c = 0
			items + 1
		EndIf
		*c + SizeOf(Character)
	Until *c > ?FruitListend
	ProcedureReturn items
EndProcedure

Debug CountData() ; you get a number and paste it into the "FruitListend:" label.
CompilerEndIf
Debug PeekI(?FruitListend) ; use the resulting number instead of calculating it.

DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Apricot"
	Data.s "Banana", "Pear"
	Data.s "Peach", "Tangerine"
	FruitListend:
	Data.i 8
EndDataSection

Re: Counting Items in the DataSection?

Posted: Sun May 04, 2025 12:50 pm
by breeze4me
I don't actually like this, but you can do it like this. It's just an example to show that it can be done this way too.

Requirement:
1. The DataSection must be before the part where you want to get the number of item strings.
2. Have a fixed number of strings per line. In the example below, 2.
3. There shouldn't be any other lines (commented lines, empty lines, etc.) inside the DataSection.

Code: Select all

#FruitList_S = #PB_Compiler_Line
DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Apricot"
	Data.s "Banana", "Pear"
	Data.s "Peach", "Tangerine"
EndDataSection
#FruitList_E = #PB_Compiler_Line

Debug (#FruitList_E - #FruitList_S - 4) * 2      ; 2 = Two strings per line.

Code: Select all

#FruitList_S = #PB_Compiler_Line
DataSection
	FruitList:
	Data.s "Apple", "Orange"
	Data.s "Mango", "Apricot"
	Data.s "Banana", "Pear" 
	;Data.s "Peach", "Tangerine"    ; Error! This commented line must be removed.
	Data.s "Peach", "Tangerine"
EndDataSection
#FruitList_E = #PB_Compiler_Line

;Debug (#FruitList_E - #FruitList_S - 4) * 2
MessageRequester("", Str((#FruitList_E - #FruitList_S - 4) * 2))