Newsgroup: it.comp.lang.visual-basic
Titolo: Le cose più banali sono le più difficili: assegnare una stringa ad un array

Vi scrivo perchè stamattina mi è caduto uno dei primi e maggiori
insegnamenti sulla programmazione che io abbia mai ricevuto ed inoltre
perchè, come sempre, ho provato a cercare su google, ma il mio problema
principale è come formulare la richiesta ;)
Allora: per assegnare una stringa ad un array, ho sempre fatto qualcosa che
in visual basic dovrebbe tradursi in questo modo:
dim serial as string
dim v(25) as byte
For i = 0 To Len(serial)
  v(i) = serial(i)
Next i
cosa che però mi da' errore di tipo non corrispondente.
Ok, non sarà byte? E allora che tipo devo metterci? Il tipo char non
esiste, ho provato
dim v(25) as string * 1 ma ovviamente nulla.
Ho provato anche 
dim serial as string
dim v(25) as string
For i = 0 To Len(serial)
  v(i) = mid$(serial,i,1)
Next i
ma mi da' errore di chiamata di routine non valida.
Poi mi sono documentato sul libro di francesco balena ed ho scoperto una
cosa bellissima: se scrivo
dim v() as byte
dim serial as string
v()=string
ho automaticamente assegnato tutta la stringa al vettore.
Ma se io non volessi farlo così, ma assegnando carattere per carattere??
E poi, quali sono le differenze in termini di prestazioni?
Grazie mille a chi vorrà darmi delucidazioni.

 v()=string
dovrebbe essere v()=serial, ma anche qui ci siamo capiti ;)

Ma se io non volessi farlo così, ma assegnando carattere per carattere??
Parto dall'ipotesi che tu voglia assegnare il valore ASCII di ciascun
carattere. Allora, 2 soluzioni:
1) inefficiente, usi la funzione ASC:
For i = 0 To Len(serial)
  v(i) = Asc(serial(i))
Next i
2) stramaledettamente efficiente, usi CopyMemory e alcune
caratteristiche di VB:
Public Declare Sub CopyMemory _
    Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)
...
    ReDim v(Len(serial) + 1)
    CopyMemory v(0), ByVal serial, Len(serial)
(e, per fare l'opposto)
    CopyMemory ByVal serial, v(0), Len(serial)
--
Ciao!
Luca Menegotto

 Grazie mille a chi vorrà darmi delucidazioni.
Premessa: VB lavora principalmente con stringhe unicode, ovvero ogni
carattere non è un byte come avveniva in ANSI C, ma è un integer (due
byte).
Questa premessa è importante per capire come assegnare una stringa ad un
array.
Vediamo meglio:
dim S as string
S="ciao"
S è *già* un array di integer, solo che vb non ti lascia accedere ai suoi
elementi se non tramite le funzioni di manipolazione stringa (mid$, left$,
ecc...)
Un escamotage possibile è usare l'api copymem (non sono sicuro si chiami
così) e copiare tutto in un bell'array (di byte o di integer a seconda del
genere di manipolazione che vuoi fare).
Altro modo per copiare il contenuto in un array:
dim A() as byte
A=S
MsgBox a
Facile e veloce, perchè  non dovrebbe andarti bene? Nota solo che A non ha
4 elementi come ti attenderesti, ma 8 perchè, ripeto, VB lavora con
caratteri da due byte.
l'assegnamento carattere per carattere deve passare necessariamente per la
conversione da carattere a numero usando la funzione Asc.
Ancora, nota che Asc() restituisce un integer.
Se ti limiti a voler che funzionino i caratteri ANSI ti basta fare così:
Dim b As Long
Dim S As String
Dim A() As Byte
S = "ciao"
ReDim A(2 * Len(S) - 1)
For b = 0 To Len(S) - 1
    A(b + b) = Asc(Mid$(S, b + 1, 1))
Next
MsgBox A
Questo programma andrà in errore con caratteri particolari (es. orientali)
perchè ASC restituisce integer mentre l'array A contiene solo byte
termoPilucco
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 ho automaticamente assegnato tutta la stringa al vettore.
Infatti... un'altro sistema e'
v = StrConv(serial, vbFromUnicode)
e sono in entrambi i casi piu' performanti del ciclo, su stringe lunghe
Ciao
-- 
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown 

Perfette spiegazioni, non c'è che dire!
Mi ero accordo del problema degli elementi di indice dispari causato dal
fatto che sono stringhe unicode, quindi devo fare il ciclo andando di 2 in
2.
Per il fatto che la mid$ lavori in base 1 mi hai dato un notevole
suggerimento, proprio non lo sapevo! 
Grazie ancora a tutti.

 Vi scrivo perchè stamattina mi è caduto uno dei primi e maggiori
Option Explicit
Private Sub Command1_Click()
Dim a As String
Dim n As Long
Dim M() As Byte
Dim Lung As Long
Dim pos As Long
a = "pontepe+µ__tippetapete@ç°"
Lung = Len(a)
pos = 0
ReDim M(1 To Lung)
For n = 1 To Lung
    pos = pos + 1
    M(pos) = AscB(Mid(a, n, 1))
Next
For n = 1 To Lung
    Debug.Print M(n), ":"; Chr(M(n))
Next
End Sub
AscB è la risposta se lo vuoi ficcare in un byte!

devi usare Mid come sotto
Ovvio. Comunque, son felice, anche oggi la mia c...ta l'ho scritta...
:((((
--
Ciao!
Luca Menegotto

Paolo C. wrote:
UO'
ma ti sei scaricato l'esempio?
????



Quale esempio? Quello della crittografia del seriale dell'HD?
Certo! 
E' ottimo per quello che cercavo, grazie.
Devo solo cercare di variare un po' piů il risultato, mi esce qualcosa come 
36353930323334 troppi 3 ;)
Grazie ancora a tutti.