Home All Groups Group Topic Archive Search About

Array saving question (lbound)

Author
11 Sep 2010 5:30 PM
Boris P.
Hello!

I am saving an array to a file and then load it again.


     Open sPath For Binary As #iFile1

     If uLoad Then
         Get #iFile1, , uArray
     Else
         Put #iFile1, , uArray
     End If

My array looks like this:

Redim myArr(1 to 3) as long
myArr(1) = 100
myArr(2) = 500
myArr(3) = 10000

When I load it again, I say:

Redim MyNewArr(1 to 3) and call the above sub.

For some reason, MyNewArr now looks like this:

MyNewArr(0) = 100
MyNewArr(1) = 500
MyNewArr(2) = 3

When I try to access MyNewArr(3) an out of bounds error is thrown.

Can somebody please tell me how to save my array correctly so that it
will start at 1 again, just like I declared it when redimming it?

Thank you!

Author
11 Sep 2010 9:06 PM
GS
on 9/11/2010, Boris P. supposed :
Show quoteHide quote
> Hello!
>
> I am saving an array to a file and then load it again.
>
>
>      Open sPath For Binary As #iFile1
>
>      If uLoad Then
>          Get #iFile1, , uArray
>      Else
>          Put #iFile1, , uArray
>      End If
>
> My array looks like this:
>
> Redim myArr(1 to 3) as long
> myArr(1) = 100
> myArr(2) = 500
> myArr(3) = 10000
>
> When I load it again, I say:
>
> Redim MyNewArr(1 to 3) and call the above sub.
>
> For some reason, MyNewArr now looks like this:
>
> MyNewArr(0) = 100
> MyNewArr(1) = 500
> MyNewArr(2) = 3
>
> When I try to access MyNewArr(3) an out of bounds error is thrown.
>
> Can somebody please tell me how to save my array correctly so that it will
> start at 1 again, just like I declared it when redimming it?
>
> Thank you!

By default arrays are zero based. So a 3 element array will always
begin with 0 and end with 2. You have to declare Option Base to 1 if
you want to go that way. However, I strongly recommend you modify your
thinking to use the default zero base. (It'll make life much
easier!<g>)

--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Author
11 Sep 2010 9:29 PM
dpb
GS wrote:
Show quoteHide quote
> on 9/11/2010, Boris P. supposed :
>> Hello!
>>
>> I am saving an array to a file and then load it again.
>>
>>
>>      Open sPath For Binary As #iFile1
>>
>>      If uLoad Then
>>          Get #iFile1, , uArray
>>      Else
>>          Put #iFile1, , uArray
>>      End If
>>
>> My array looks like this:
>>
>> Redim myArr(1 to 3) as long
>> myArr(1) = 100
>> myArr(2) = 500
>> myArr(3) = 10000
>>
>> When I load it again, I say:
>>
>> Redim MyNewArr(1 to 3) and call the above sub.
>>
>> For some reason, MyNewArr now looks like this:
>>
>> MyNewArr(0) = 100
>> MyNewArr(1) = 500
>> MyNewArr(2) = 3
>>
>> When I try to access MyNewArr(3) an out of bounds error is thrown.
>>
>> Can somebody please tell me how to save my array correctly so that it
>> will start at 1 again, just like I declared it when redimming it?
>>
>> Thank you!
>
> By default arrays are zero based. So a 3 element array will always begin
> with 0 and end with 2. You have to declare Option Base to 1 if you want
> to go that way. However, I strongly recommend you modify your thinking
> to use the default zero base. (It'll make life much easier!<g>)

I'd say "it depends" on whether to use 0- or 1-based indexing, dependent
upon the problem domain.

Note that ReDim() should _not_ be used except for redimensioning, not
for initial declarations  -- see the Caution discussion in the language
reference manual for ReDim.

In short, the above code snippet should start w/ a

Dim myArr() As Long
ReDim myArr(1 to 3)

There's a problem w/ the code and the symptoms described as well--I
strongly suspect the code isn't as typed in (and can tell it isn't
copied and pasted as the capitalization for keywords isn't consistent w/
the VB stylistic pattern).

The statement

Redim MyNewArr(1 to 3)

isn't complete, either, as the "As Long" clause is missing and the
existence of the (1 To 3) if it were in the actual code would preclude
the appearance of MyNewArr(0) as the upper and lower bound subscripts
are explicitly given.

I suspect that what you _actually_ have is

ReDim MyNewArr(3)

instead which would behave as GS notes assuming there is no

Option Base 1

statement in effect.

Lesson to be learned -- when posting code that is to demonstrate a
symptom, post the actual code and the symptom, not a paraphrasing of it.

--
Author
12 Sep 2010 7:13 AM
Boris P.
Yes, you're right, thanks! I did make the mistake of typing (0 to 3)
instead of (1 to 3).
I am glad I mistyped it and you noticed that it was not copied!

The reason why I use 1-based arrays is that else I can never say if an
array is actually empty!

Let's take a real-life sample:

I have a public var name colMyCustomers() which is made of udts

Public Type udtCustomer
    FirstName as string
    LastName as string
    (etc...)
End Type

public sub GetCustomers()

    Redim colCustomers(0)

    dim r as dhrichclient.crecordset
    set r = cn.openrecordset("SELECT * FROM customers")

    redim colCustomers(1 to r.recordcount)
    dim l&
    for l = 1 to r.recordcount
        colCustomers(l).firstname = r!customer_firstname
        colCustomers(l).lastname = r!customer_lastname
        (etc...)
      r.movenext
    next l

end sub

The later in the code when I access the array, I can simply say

For l = 1 to ubound(colcustomer)
    etc...
Next l

When the array is still empty, it will simply skip it.
What would I do if the array was 0 based?

I would have to store in another variable if the array is really empty
or has 1 customer (=colCustomer(0)).

And if I had not redimmed the array to 0 (Redim colCustomers(0)), any
attemps to do something like this

For l = 1 to ubound(colcustomer)
    etc...
Next l

would throw an error because the array is not dimmed.

Anything wrong with my method?



dpb wrote:
Show quoteHide quote
> GS wrote:
>> on 9/11/2010, Boris P. supposed :
>>> Hello!
>>>
>>> I am saving an array to a file and then load it again.
>>>
>>>
>>> Open sPath For Binary As #iFile1
>>>
>>> If uLoad Then
>>> Get #iFile1, , uArray
>>> Else
>>> Put #iFile1, , uArray
>>> End If
>>>
>>> My array looks like this:
>>>
>>> Redim myArr(1 to 3) as long
>>> myArr(1) = 100
>>> myArr(2) = 500
>>> myArr(3) = 10000
>>>
>>> When I load it again, I say:
>>>
>>> Redim MyNewArr(1 to 3) and call the above sub.
>>>
>>> For some reason, MyNewArr now looks like this:
>>>
>>> MyNewArr(0) = 100
>>> MyNewArr(1) = 500
>>> MyNewArr(2) = 3
>>>
>>> When I try to access MyNewArr(3) an out of bounds error is thrown.
>>>
>>> Can somebody please tell me how to save my array correctly so that it
>>> will start at 1 again, just like I declared it when redimming it?
>>>
>>> Thank you!
>>
>> By default arrays are zero based. So a 3 element array will always
>> begin with 0 and end with 2. You have to declare Option Base to 1 if
>> you want to go that way. However, I strongly recommend you modify your
>> thinking to use the default zero base. (It'll make life much easier!<g>)
>
> I'd say "it depends" on whether to use 0- or 1-based indexing, dependent
> upon the problem domain.
>
> Note that ReDim() should _not_ be used except for redimensioning, not
> for initial declarations -- see the Caution discussion in the language
> reference manual for ReDim.
>
> In short, the above code snippet should start w/ a
>
> Dim myArr() As Long
> ReDim myArr(1 to 3)
>
> There's a problem w/ the code and the symptoms described as well--I
> strongly suspect the code isn't as typed in (and can tell it isn't
> copied and pasted as the capitalization for keywords isn't consistent w/
> the VB stylistic pattern).
>
> The statement
>
> Redim MyNewArr(1 to 3)
>
> isn't complete, either, as the "As Long" clause is missing and the
> existence of the (1 To 3) if it were in the actual code would preclude
> the appearance of MyNewArr(0) as the upper and lower bound subscripts
> are explicitly given.
>
> I suspect that what you _actually_ have is
>
> ReDim MyNewArr(3)
>
> instead which would behave as GS notes assuming there is no
>
> Option Base 1
>
> statement in effect.
>
> Lesson to be learned -- when posting code that is to demonstrate a
> symptom, post the actual code and the symptom, not a paraphrasing of it.
>
> --
Author
11 Sep 2010 10:31 PM
MikeD
"GS" <gesan***@netscape.net> wrote in message
news:i6gr11$u8s$1@news.eternal-september.org...
> on 9/11/2010, Boris P. supposed :

>
> By default arrays are zero based. So a 3 element array will always begin
> with 0 and end with 2. You have to declare Option Base to 1 if you want to
> go that way. However, I strongly recommend you modify your thinking to use
> the default zero base. (It'll make life much easier!<g>)


No, that's incorrect. If you do NOT specify a lower bound, only then the
default is 0.  Otherwise, the lower bound is whatever you specify in your
Dim/ReDim. Option Base 1 just means that if you DON'T specify the lower
bound, it will default to 1 instead of 0.

I also can't agree with your recommendation. In some cases, sure, the array
should be 0-based.  For example, if syncing it to something that is 0-based
(a listbox, for example). Otherwise, I personally view it as "programmer's
preference".

--
Mike
Author
12 Sep 2010 1:34 AM
GS
MikeD submitted this idea :
Show quoteHide quote
>
> "GS" <gesan***@netscape.net> wrote in message
> news:i6gr11$u8s$1@news.eternal-september.org...
>> on 9/11/2010, Boris P. supposed :
>
>>
>> By default arrays are zero based. So a 3 element array will always begin
>> with 0 and end with 2. You have to declare Option Base to 1 if you want to
>> go that way. However, I strongly recommend you modify your thinking to use
>> the default zero base. (It'll make life much easier!<g>)
>
>
> No, that's incorrect. If you do NOT specify a lower bound, only then the
> default is 0.

That was implied in the context of the OP's problem! Dumping a file
into an array with 'Get' will result in a zero-based array UNLESS
Option Base 1 is declared. That's all I was responding to.

>  Otherwise, the lower bound is whatever you specify in your
> Dim/ReDim. Option Base 1 just means that if you DON'T specify the lower
> bound, it will default to 1 instead of 0.

No disagreement here.

>
> I also can't agree with your recommendation. In some cases, sure, the array
> should be 0-based.  For example, if syncing it to something that is 0-based
> (a listbox, for example). Otherwise, I personally view it as "programmer's
> preference".

And as a programmer's preference, it was my recommendation to not use
it 'generally speaking'! Again, no disagreement that it does have a
place if one chooses to accept the resposibility of managing it in
those cases. Personally, I've never found any practical reasons to
suffice using Option Base 1.<g>

Not to raise contention.., but just to clarify!

--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Author
12 Sep 2010 1:52 AM
dpb
GS wrote:
....

> That was implied in the context of the OP's problem! Dumping a file into
> an array with 'Get' will result in a zero-based array UNLESS Option Base
> 1 is declared. That's all I was responding to.
....

The Get doesn't really have anything to do with...unless the variable
has been declared as a variable, it's a scalar and only a single value
will be returned on the Get (ignoring the details of descriptors for
dynamic strings/arrays or UDTs).

The dimensions of the array are based on the Dim or ReDim used and the
Option Base in effect at the time.

The problem w/ OP's posting is that his posted code doesn't reflect the
actual code--it's missing the definition of the calling sequence in the
subroutine snippet and the location with respect to that of where he
looked at the data and how.  The array name he complains of isn't the
same as the array name in the routine so it isn't that that caused the
problem.

There's also the problem noted above of whether he's reading/writing the
same type of array -- if it was dynamic on Put, it needs to be dynamic
matching on Get or he's going to get the descriptor information
confounded w/ the data.  Conversely, if Put a fixed-sized array, only
the data (no descriptors) will be written and trying to read it into a
dynamic array will confound the data w/ descriptors the other direction.

The upshot still is, OP needs to post the actual code to be able to see
precisely what caused the specific symptom(s) but he's got problems of
inconsistency and poor practice at a minimum...

--
Author
12 Sep 2010 1:54 AM
dpb
dpb wrote:
....

> The Get doesn't really have anything to do with...unless the variable
> has been declared as a variable, ...

That of course was intended to read "declared as an array, ..."

--
Author
12 Sep 2010 3:27 AM
GS
Well stated.., and I agree.

Sorry I wasn't giving focus past the use of 'Get' and 'Put' in the
concept of the posted code so much as how the array[s] were dimmed
going to and coming back from the file.

As far as I'm concerned, my experience bears out that both you and Mike
D have made valid points that I fully agree with. Personally, I've
never mixed static/dynamic arrays in this usage knowing that Put/Get
require everything be the same both ways or there's going to be
problems.

Just seemed the LBound/UBound issue was related to the Option Base used
(or not used)<g>

--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Author
12 Sep 2010 7:52 AM
Boris P.
But the actual problem remains:

How would one know if an array is empty when it's zero based???

I don't understand people who use 0-based arrays because they have to
use another variable to check if the array is really empty.

With 0-based I mean arrays that have data in the index 0 position.
I do use 0-based arrays as well, but it doesn't contain data at that
position.

I only use it to check if the array is "empty" or not.
Author
12 Sep 2010 8:08 AM
Boris P.
Perhaps everybody will understand my way of coding with this sample.
I think it's really beautiful code:

Private Sub Form_Load()

     Dim s() As String
     ReDim s(0)

     Debug.Print "We have " & UBound(s) & " items"
     Dim l&
     For l = 1 To UBound(s)
         'if array is redimmed to 0, it will simply skip here
         Debug.Print "Item value " & l & " is " & s(l)
     Next l

     ReDim s(1)
     Debug.Print "We have " & UBound(s) & " items"
     For l = 1 To UBound(s)
         Debug.Print "Item value " & l & " is " & s(l)
     Next l

End Sub
Author
12 Sep 2010 7:48 AM
Boris P.
dpb wrote:
Show quoteHide quote
> GS wrote:
> ...
>
>> That was implied in the context of the OP's problem! Dumping a file
>> into an array with 'Get' will result in a zero-based array UNLESS
>> Option Base 1 is declared. That's all I was responding to.
> ...
>
> The Get doesn't really have anything to do with...unless the variable
> has been declared as a variable, it's a scalar and only a single value
> will be returned on the Get (ignoring the details of descriptors for
> dynamic strings/arrays or UDTs).
>
> The dimensions of the array are based on the Dim or ReDim used and the
> Option Base in effect at the time.
>
> The problem w/ OP's posting is that his posted code doesn't reflect the
> actual code--it's missing the definition of the calling sequence in the
> subroutine snippet and the location with respect to that of where he
> looked at the data and how. The array name he complains of isn't the
> same as the array name in the routine so it isn't that that caused the
> problem.
>
> There's also the problem noted above of whether he's reading/writing the
> same type of array -- if it was dynamic on Put, it needs to be dynamic
> matching on Get or he's going to get the descriptor information
> confounded w/ the data. Conversely, if Put a fixed-sized array, only the
> data (no descriptors) will be written and trying to read it into a
> dynamic array will confound the data w/ descriptors the other direction.
>
> The upshot still is, OP needs to post the actual code to be able to see
> precisely what caused the specific symptom(s) but he's got problems of
> inconsistency and poor practice at a minimum...
>
> --


My code is huge and I cannot post it without leaving out things, and to
make it clear, I rewrote it on the fly.

But my actual problem was that when I declared/ dimmed/ redimmed it, I chose

Redim (1 to ...)
and saved it this way.

But before loading it again from the file on the disk, I said "Redim (0
to ...)"

This caused the array to start at 0 instead of 1.

Learnt something...

Normally, I only use DBs to write my data, not binary files, that's why
your statement of "lack of consistency and practice" is right in this case.