OVH Cloud OVH Cloud

Je deviens fou!

9 réponses
Avatar
julien
Bonjour
Je ne comprends rien du tout à ce que se passe à l'intétieur d'une de
mes méthodes! J'essaye de récupérer toutes les données d'un
RandomAccessFile:
chaque record contient 5 valeurs d'unte taille maximale de 100 (int
size[] = {100,100,100,100,100}), et la prmière valeur d'un record est
toujours non nulle.
Le fichier contient 2 records:
A B C D E
V W X Y Z

Voici ma métode

public String[][] getAllRecords() {

String values[] = new String[size.length];
for (int count = 0; count<values.length; count++) {
values[count] = null;
}

String results[][] = {values};

if (openRead() == 1) { // open for reading
String current = "";
int pos = 0;
int res = 0;

do {
for (int count = 0; count < size.length; count++) {
try {
stream.seek(pos);
current = "";

char value = (char) stream.read();

while ((byte) value > 0) {
current += value;
value = (char) stream.read();
}
}
catch (IOException ioException) {
return results;
}

values[count] = current;

pos += size[count];
}

if (! values[0].equals("")) {
if (res == 0) {
results[0] = values;
-->(1)
}
else {
-->(2)
String temp[][] = results;
-->(3)
results = new String[temp.length + 1][values.length];
for (int count = 0; count < temp.length; count++) {
results[count] = temp[count];
}
results[res] = values;
}

}
res++;
}
while (! values[0].equals(""));

close();
-->(4)
return results;
}
else { //cannot open the file
return results;
}
}


Voici les valeurs à différents points:
-->(1)
results: {A B C D E}
c'est ce qui est attendu

->(2)
results: {V W X Y Z}
Comment results a bien pu changé! Il devrait contenir la même chose
qu'au -->(1) vu que rien ne l'a modifié!

-->(3)
temp: {V W X Y Z}
Normal vu -->(2)

-->(4)
results contient 2 "lignes" vides!!!!!!


J'ai passé plusieurs heures dessus, je ne comprends absolument pas ce
aue se passe. J'ai l'impression que les valeurs changent toutes seuls
dans result, par magie!! C'est à devenir fou!

Merci pour tout eclaircissement

Julien

9 réponses

Avatar
Thibaut Desmarest
julien wrote:

if (! values[0].equals("")) {
if (res == 0) {
results[0] = values;
-->(1)
}
else {
-->(2)
String temp[][] = results;
-->(3)
results = new String[temp.length + 1][values.length];
for (int count = 0; count < temp.length; count++) {
results[count] = temp[count];
}
results[res] = values;
}

Voici les valeurs à différents points:
-->(1)
results: {A B C D E}
c'est ce qui est attendu

->(2)
results: {V W X Y Z}
Comment results a bien pu changé! Il devrait contenir la même chose
qu'au -->(1) vu que rien ne l'a modifié!

-->(3)
temp: {V W X Y Z}
Normal vu -->(2)

-->(4)
results contient 2 "lignes" vides!!!!!!


J'ai passé plusieurs heures dessus, je ne comprends absolument pas ce
aue se passe. J'ai l'impression que les valeurs changent toutes seuls
dans result, par magie!! C'est à devenir fou!

Merci pour tout eclaircissement

Julien


Pour (1) et (2), c'est soit l'un soit l'autre normallement, puisque ton
else correspond à ton deuxième if. Donc si tu passes en 1, tu ne passes
pas en 2. Non ?

Sinon je te conseille à l'avenir d'indenter ton code de manière
"propre". Tu verras que tu t'y retrouveras mieux et que tu y verras bien
plus clair dans ton code. Tu devrais ainsi éviter des erreur bêtes.

Thibaut

Avatar
Thomas Nguyen
On Mon, 18 Oct 2004 10:08:31 +0200, Thibaut Desmarest wrote:
je te conseille à l'avenir d'indenter ton code de manière
"propre". Tu verras que tu t'y retrouveras mieux et que tu y verras bien
plus clair dans ton code. Tu devrais ainsi éviter des erreur bêtes.


J'ai pas vu trop de problèmes d'indentation.
En fait, j'ai beau essayer très fort, j'arrive pas à lire le programme.
Je crois avoir compris la structure du fichier (sauf la fin de fichier) et
je saurais écrire le programme pour lire ce fichier, mais ce
programme-ci est illisible pour moi.

Pour moi, le problème principal est le nommage des variables. Les noms ne
sont absolument pas descriptifs, ça m'embrouille terriblement.


Autres remarques en vrac:
- Pour accumuler des lignes de String[], ça me parait judicieux
d'utiliser un ArrayList ou un LinkedList. Là, c'est inutilement lourd de
réallouer et recopier entièrement un tableau à chaque nouvelle ligne. -
Je vois pas l'utilité du RandomAccessFile. Puisque la taille des
enregistrements est connue, autant lire en séquentiel, sans s'encombrer
à gérer la position dans le fichier.
- L'initialisation du tableau values[] à zéro au début est inutile. On
est pas en C.
- des commentaires pour indiquer à quoi sert chaque morceau
de code seraient les bienvenus. D'habitude, le nommage des variables
locales sert de documentation primitive, mais là c'est nécessaire.


Pour finir, je citerais un de mes profs d'info (il a peut-être piqué la
citation à un autre, mais elle est appropriée):
"Si tu sais pas quel nom donner à ta variable, c'est que tu en as pas
besoin."


-- Thomas

Avatar
julien
Thomas Nguyen wrote:
à gérer la position dans le fichier.
- L'initialisation du tableau values[] à zéro au début est inutile. On
est pas en C.
Pourtant à la compilation, si je ne le mets pass, j'ai l'erreur:

"results may have not been initialized".

Avatar
julien
Thomas Nguyen wrote:
- Pour accumuler des lignes de String[], ça me parait judicieux
d'utiliser un ArrayList ou un LinkedList. Là, c'est inutilement lourd de
réallouer et recopier entièrement un tableau à chaque nouvelle ligne. -


Cela semble une bonne idée (je ne connaissais pas ArrayList), mais je
bute sur un probleme:
* je dois retourner un tableau à 2 dimensions: table[][]
* j'ajoute des tableaux à 1 dimenseion dans ma liste: liste.add(array[])
* à la fin, comment récupérer mon tableau à 2 dimenseions?
list.toArray() me donne uniquement tableau[], pas tableau[][].


Merci
Julien

Avatar
Laurent Bossavit
Julien,

->(2)
results: {V W X Y Z}
Comment results a bien pu changé! Il devrait contenir la même chose
qu'au -->(1) vu que rien ne l'a modifié!


Suite à ton initialisation:
String results[][] = {values};


La première case de "results" contient une référence vers "values" - et
pas, comme tu l'as peut-être supposé, une copie.

Dès lors, si tu modifies "values" - ce que fait la première partie de ta
boucle - ce que tu lis en déréférençant "results" sera différent.

Laurent
http://bossavit.com/thoughts/

Avatar
Thibaut Desmarest
Thomas Nguyen wrote:

On Mon, 18 Oct 2004 10:08:31 +0200, Thibaut Desmarest wrote:

je te conseille à l'avenir d'indenter ton code de manière
"propre". Tu verras que tu t'y retrouveras mieux et que tu y verras bien
plus clair dans ton code. Tu devrais ainsi éviter des erreur bêtes.



J'ai pas vu trop de problèmes d'indentation.
En fait, j'ai beau essayer très fort, j'arrive pas à lire le programme.
Je crois avoir compris la structure du fichier (sauf la fin de fichier) et
je saurais écrire le programme pour lire ce fichier, mais ce
programme-ci est illisible pour moi.


Ca doit être Mozilla qui lit pas le texte de la même manière que chez
toi alors, autant pour moi donc mais mon conseil tient toujours.

Pour moi, le problème principal est le nommage des variables. Les noms ne
sont absolument pas descriptifs, ça m'embrouille terriblement.


+1


Avatar
Thomas Nguyen
On Mon, 18 Oct 2004 18:32:19 -0700, julien wrote:

Thomas Nguyen wrote:
à gérer la position dans le fichier.
- L'initialisation du tableau values[] à zéro au début est inutile. On
est pas en C.
Pourtant à la compilation, si je ne le mets pass, j'ai l'erreur:

"results may have not been initialized".


Dans ton code, la ligne
String values[] = new String[size.length];
suffit à initialiser la variable avec une référence à un tableau de
taille size.length et ne contenant que des références nulles.

Ca:
for (int count = 0; count<values.length; count++) {
values[count] = null;
}
ça met des null là où il y en a déjà, c'est inutile. ;)


Avatar
Thomas Nguyen
On Mon, 18 Oct 2004 18:55:35 -0700, julien wrote:
Thomas Nguyen wrote:
- Pour accumuler des lignes de String[], ça me parait judicieux
d'utiliser un ArrayList ou un LinkedList. Là, c'est inutilement lourd de
réallouer et recopier entièrement un tableau à chaque nouvelle ligne. -


Cela semble une bonne idée (je ne connaissais pas ArrayList), mais je
bute sur un probleme:
* je dois retourner un tableau à 2 dimensions: table[][]
* j'ajoute des tableaux à 1 dimenseion dans ma liste: liste.add(array[])
* à la fin, comment récupérer mon tableau à 2 dimenseions?
list.toArray() me donne uniquement tableau[], pas tableau[][].



Pour être précis, les tableaux à deux dimension N'EXISTENT PAS en Java.
Il n'existe que les tableaux de tableau.

La méthode toArray() retourne un Object[], dont chaque objet peut tout à
fait être un String[].



Ton code devrait ressembler à ça:

List listeDesEnregistrements = new ArrayList();
(...)
return (String[][]) listeDesEnregistrements.toArray(new String[0][]);

Je te laisse consulter la documentation pour comprendre la nécessité du
cast et du paramètre.
(mais tu peux bien sûr poser des questions si tu veux des précisions ;) )


-- Thomas


Avatar
julien
Laurent Bossavit wrote:
Suite à ton initialisation:

String results[][] = {values};



La première case de "results" contient une référence vers "values" - et
pas, comme tu l'as peut-être supposé, une copie.

Dès lors, si tu modifies "values" - ce que fait la première partie de ta
boucle - ce que tu lis en déréférençant "results" sera différent.

Laurent
http://bossavit.com/thoughts/


Merci beaucoup, ça explique tout!