Vai al contenuto


antinomau96

Java - Loop infinito lettura dati da file

Recommended Posts

Salve,
mi sto cimentando in un programma che prende degli interi da file, li memorizza in un array e li ordina mediante il metodo per fusione.
Sembrerà strano ma la cosa che più mi sta dando filo da torcere è la lettura da file.
Il mio obiettivo è quello di leggere degli interi in un file dove ci sono parole e numeri ma il problema è che i metodi
hasNext()
e
hasNextInt()

 

sembrano non funzionare e pertanto adesso sto provando semplicemente a leggere degli interi da file.
Posto un pezzo di codice per spiegare meglio la situazione:

Questo è il codice che si occupa di contare quanti numeri ci sono nel file

int numofint = 0; //questa variabile viene creata per poter salvare il numero di interi presenti nel file

while (in.hasNext())
{
   numofint++; //la variabile numofint viene incrementata
} //end of while

Questo ciclo while entra in un loop senza fine.... Non riesco comprendere il motivo...

Il resto del codice che si occupa di inserire gli interi nell'array è:

array = new int[numofint+1];

in.reset(); //reset dello scanner

int i=-1;
while (in.hasNext())
{
   i++;

   array[i] = Integer.parseInt(in.next());

} //end of while

Spero vivamente che qualcuno possa aiutarmi:angiolettoim:

Questo è il codice dell'intero programma (quello scritto fin ora):

package com_antomau_OrdFusRicBin.UserInterface;

import java.util.Scanner;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.Arrays;

/**
 * 
 * @author Antonio Maulucci
 *
 */
public class UserOrdFusRicBin {
	
	private static File file; //nuovo file
	
	private static Scanner in; //nuovo scanner
	
	/*
	 * fileLoaded -> verifica che il file sia stato correttaamente caricato
	 * arraySorted -> verifica che l'array sia stato ordinato
	 */
	private static boolean fileLoaded = false;
	private static int[] array;
	
	public static void main(String[] args) {
		
		
		JFrame f = new JFrame("OrdFus-RicBin");
		f.setSize(300, 300);
		f.setLayout(new BorderLayout());
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel fileFinder = new JPanel();
		fileFinder.setLayout(new GridLayout(1,3));
		
		JFileChooser fileChooser = new JFileChooser();
		
		JLabel choosenFileName = new JLabel(""); 
		JButton openFileButton = new JButton("Open database");
		JButton exitButton = new JButton("Exit");
		
		fileFinder.add(choosenFileName);
		fileFinder.add(openFileButton);
		fileFinder.add(exitButton);
		
		
		JPanel contentPanel = new JPanel();
		contentPanel.setLayout(new BorderLayout());
		
		JPanel consolePanel = new JPanel();
		consolePanel.setLayout(new GridLayout(1,4));
		
		JButton printArrayButton = new JButton("Print data");
		JButton sortButton = new JButton("Sort");
		
		consolePanel.add(printArrayButton);
		consolePanel.add(sortButton);
		
		JPanel mainContents = new JPanel();
		
		contentPanel.add(consolePanel, BorderLayout.NORTH);
		contentPanel.add(mainContents, BorderLayout.CENTER);
		
		f.add(fileFinder, BorderLayout.NORTH);
		f.add(contentPanel, BorderLayout.CENTER);
		
		
		f.pack();
		
		class openFileListenerClass implements ActionListener {
			@Override
			public void actionPerformed(ActionEvent e) {
				fileChooser.showOpenDialog(f); //questa istruzione visualizza la finestra di dialogo per la scleta del file all'interno del frame f
				try {
					file = fileChooser.getSelectedFile();
					in = new Scanner(file); //creare uno scanner per il file "file"
					fileLoaded = true; //diventa vera perché il file è stato caricato
					
				} catch (FileNotFoundException ex) {
					ex.printStackTrace();
				} //end of try/catch
				//\\//\\//\\//\\//\\//
				if (fileLoaded)
				{

					int numofint = 0; //questa variabile viene creata per poter salvare il numero di interi presenti nel file

					while (in.hasNext())
					{
						numofint++; //la variabile values viene incrementata
					} //end of while

					array = new int[numofint+1];

					in.reset(); //reset dello scanner

					int i=-1;
					while (in.hasNext())
					{
						i++;

						array[i] = Integer.parseInt(in.next());

					} //end of while

				} //end of if fileLoaded
				//\\//\\//\\//\\//\\//
				choosenFileName.setText(fileChooser.getName(file));
			}
		} //end of selectFileListenerClass
		
		ActionListener openFileListener = new openFileListenerClass();
		openFileButton.addActionListener(openFileListener);
		
		
		class exitListenerClass implements ActionListener {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		} //end of openFileListenerClass
		
		ActionListener exitListener = new exitListenerClass();
		exitButton.addActionListener(exitListener);
		
		class printDataButtonListenerClass implements ActionListener {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (fileLoaded) {
					mainContents.removeAll();
					JLabel printArrayLabel = new JLabel(Arrays.toString(array));
					mainContents.add(printArrayLabel);
					f.pack();
				} //end of if
			}
		} //end of openFileListenerClass
		
		ActionListener printDataListener = new printDataButtonListenerClass();
		printArrayButton.addActionListener(printDataListener);
		
	} //end of main

} //end of class

Altri modi in cui ho provato ad implementare la lettura del numero di token e ad inserire questi nell'array sono stati:

metodo 1

if (fileLoaded) { //linea 93
   int[] k = new int[256];
   int i=-1;
   while (in.hasNext())
   {
      i++;
      k[i] = in.nextInt();
      System.out.print(i + " "); //debug
   } //end of while
   System.out.println("i = " + i); //debug
   array = new int[i+1];
   for (int j=0; j<i; j++) {
      array[i] = k[i];
   }
   System.out.println(Arrays.toString(array)); //debug
} //end of if

metodo 2

if (fileLoaded) { //linea 93
               //questa variabile salva il numero di elementi che dovrà contenere l'array di interi
               int values=0;
               while (in.hasNext()) values++;
               array = new int[values-1]; //l'array "array" viene inzializzato con n-1 posizioni dove n sono gli elementi da inserire (values) (n-1 perché le posizioni dell'array partono da 0, per 3 elementi servono 2 posizioni perché 0,1,2)
               int i = -1; //indice dell'array in cui inserire il dato corrente (vedi commento di "i++" per comprendere perché il suo valore è (-1)
               while (in.hasNext()) { // questo ciclo while verifica che nel file ci sia un dato successivo a quello seguente
                  if (in.hasNextInt()) {
                     /*
                      * l'indice dell'array viene incrementato per permettere di inserire il dato nel nuovo indice dell'array
                      * esso viene inzializzato a -1 per fare in modo che l'indice i sia incrementato prima dell'inserimento del nuovo dato
                      *  questo modo si fa prima corrispondere l'indice alla posizione corretta dell'elemento da inserire
                      *  e poi si inserisce l'elemento
                      *  altrimenti avverrebbe che all'ultimo intero il dato verebbe inserito e poi verrebbe incrementato l'indice verso una posizione inesistente il che genererebbe un errore
                      */
                     i++;
                     System.out.println("debug - i is = " + i + " /// in.nextint is = " + in.nextInt());
                     array[i] = in.nextInt(); //nella posizione i dell'array viene inserto il numero intero
                  } //end of if
               } //end of while
               //
            } //end of if

metodo 3

if (fileLoaded)
{
   in.reset(); //debug
   int values = 0;
   while (in.hasNextInt())
   {
      System.out.println("i'm incrementing values"); //debug
      values++;
      System.out.println("now values is = " + values); //debug
      if (in.hasNext()) System.out.println("next value is = " + in.next()); //debug
   } //end of while
   System.out.println("at end of while value of values is = " + values); //debug
   array = new int[values+1];
   int i = -1;
   try {
      in = new Scanner(file);
   } catch(Exception ex) {
      System.out.println("unable to make scanner"); //debug
   }
   /*
   while (in.hasNextInt()) //risulta essere falso
   {
      i++;
      System.out.println("after incrementing i it's = " + i); //debug
      array[i] = in.nextInt();
      System.out.println("ending while i is = " + i + " and nextInt is = " + in.nextInt()); //debug
   } //end of while
   */
   while(in.hasNextInt())
   {
      i++;
      System.out.println("after incrementing i it's = " + i); //debug
      array[i] = in.nextInt();
      System.out.println("ending while i is = " + i + " and nextInt is = " + in.nextInt()); //debug
   } //end of while
} //end of if fileloaded

 

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti


Ciao. Ho provato il tuo programma e il problema è molto più semplice di quel che sembra.

tu usi hasNext() credendo che java incrementi il valore ad ogni ciclo... ma in realtà hasNext() ritorna solo true quando ci sono ancora parole nello Scanner e false quando non ce ne sono, ma non incrementa l'index e quindi non passa alla parola successiva.

Per incrementare l'index e passare quindi alla parola successiva dovresti fare qualcosa tipo in.next().

In questa maniera il programma non si blocca nel ciclo loop.

Poi ci sono altri problemi (provando a fare il print l'array indica tutti zeri, quindi è probabile che tu non salvi ciò che leggi nel tuo array... ma onestamente non ho analizzato tutto il codice al momento... se vuoi che lo faccia dimmi pure), però intanto il loop infinito non c'è più.

PS. Per l'altro problema stai utilizzando in.reset() pensando di poter resettare la posizione dello Scanner all'inizio del file (in realtà serve a tutt'altro). Dovresti usare una List/ArrayList (così da non dover contare il numero di elementi e poter immediatamente mettere tutto all'interno del tuo "array") oppure creare 2 scanner al posto di uno solo.

PS2. Il sort mi pare non sia stato ancora implementato, quindi direi che aggiustando queste due cose sei a posto

tanto per capirci qualcosa del genere (dove temp è un altro Scanner. puoi sostituire tutto con un unico while/for se usi una List/ArrayList al posto di un array standard):

int numofint = 0;
                    
while (temp.hasNext()){
	temp.next();
	numofint++;
}
                    
array = new int[numofint+1];
                    
int i=-1;
while (in.hasNext()){
	i++;                    
	array[i] = Integer.parseInt(in.next());
}

PS3. Ho provato a fare un paio di aggiunte. Prima di tutto ho aggiunto un metodo che controlla se l'input è un intero:

public static boolean isParsable(String input){
   boolean parsable = true;
   try{
   	Integer.parseInt(input);
   }catch(NumberFormatException e){
   	parsable = false;
   }
   return parsable;
}

Poi aggiungendo altri 2 Scanner nel primo while incremento numofint++; solo se if(isParsable(scanner.next()))

Nel secondo while se if(isParsable(altroScanner.next())){ allora i++; e array = Integer.parseInt(in.next()); else in.next();

Inoltre ho array = new int[numofint]; tolto l'elemento in più nell'array che non serviva.

Con questo la stampa degli elementi è solo degli interi. Mentre le eventuali lettere/altri caratteri vengono ignorati. Inoltre l'array non contiene nessun elemento in più. Ora ti basta davvero solo aggiungere il codice per ordinare e sei a posto.

Comunque il tuo programma mi ha divertito. Però ti consiglio di dividere il codice in classi... un'unico main diventa difficile da leggere.

Modificato da Lief

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Crea un account o accedi per lasciare un commento

You need to be a member in order to leave a comment

Crea un account

Iscriviti alla nostra comunità. È facile!

Crea un nuovo account

Accedi

Sei già iscritto? Accedi qui.

Accedi Ora

  • Contenuti simili

    • Da Notblu
      Lo scanner è usato, ma si può dire che è nuovo. L'ho acquistato nuovo e l'ho usato per scansionare i miei vecchi negativi, ora non mi serve più e lo vendo. In tutto avrà lavorato forse 2 ore, è completo dei suoi imballi originali.
        Ci sono in commercio vari tipi di scanner simili; questo è marca Relliance, più potente e prestante.   Ha una risoluzione di 14/22 MegaPixel (interpolati) ma comunque anche a 14mp la resa è buona.   Come da foto, è fornito di guide per diapositive, negativi  (35 mm, 110, 135, 126, Super 8), ma l'ho usato anche per i medio formato da 120mm (questo non ha la guida, ma si può inserire la pellicola facilmente manualmente nello scanner)   Cavo Video Out per TV Connection, l'interfaccia è USB 2.0 (cavi inclusi).  Si auto alimenta con il cavo USB tramite pc. Sistema di supporto: Windows XP / vista / Windows7 / 8 / Mac10.7.3 e versioni successive. Ha molte funzioni: è multilingua (anche italiano), è possibile visionare le foto scannerizzate in play automatico o manuale prima di scaricarle sul Pc o Mac. E' fornito di una comoda spazzola per pulire internamente il piano luce.  Dopo un po' che rimane inattivo si spegne da solo.   Si può anche selezionare il tipo di negativo: colore, bn e il formato e se la memoria interna è piena si può formattare e si svuota.   SPEDIZIONE GRATUITA! Descrizione prodotto
      Caratteristiche
      Funzione: scanner per pellicole / USB MSDC
      Interfaccia: USB 2.0
      Sensore di immagine: 14 megapixel (4416 * 3312)
      Sensore CMOS da 1 / 2,33 "
      Display: LCD TFT a colori da 2,4 "
      Controllo dell'esposizione: automatico / manuale (-2,0 EV ~ + 2,0EV)
      Bilanciamento del bianco: automatico
      Risoluzione: 14,0 megapixel / 22 megapixel (interpolazione)
      Tipo di film: 135 Film (36 * 24mm), 126KPK Film (27 * 27mm), 110 Film (17 * 13mm), anche 120mm
      Super8 Film (4.01 * 5.79mm), Monocromatico, Diapositiva
      Effetti immagine: bianco e nero, diapositive, negativi
      Formato file: Immagine: JPEG
      Tipo TV-OUT: NTSC / PAL
      Memoria integrata: 128M
      Scheda di memoria esterna: scheda SD fino a 32 GB (non inclusa)
      Alimentazione: cavo con porta USB (incluso)
      Lingua: S-cinese / T-cinese / inglese / francese / tedesco / italiano / spagnolo / giapponese
      Sistema di supporto: Windows XP / vista / Windows7 / 8 / Mac10.7.3 e versioni successive
      Formato del prodotto: L8.7XW8.7XH103mm
      Peso: 250 g
       
      Pacchetto compreso:
      1pcs * Scanner
      1 pz * Adattatore negativo
      Adattatore per diapositive 1 pz *
      1 pz * Cavo USB, 1pz * cavo TV-OUT: NTSC / PAL 1 pz * Adattatore di alimentazione (cavo USB)
      1 pz * Pennello per la pulizia
      1pcs * Manuale in inglese  
    • Da luciensabre
      Salve. Io ho un problema, credo stupido, con il mio Mac.
      Si tratta di un MacBook Pro Retina del 2014 usato (ovviamente), acquistato appena prima di Natale, già aggiornato a macOS Mojave; io sono utente amministratore di quel Mac e come tale dovrei avere tutti i permessi....peccato che non sia così: come si vede nell'immagine allegata, quando provo a cambiare i permessi mi dice che non ho i permessi necessari; lo stesso messaggio appare quando provo a fare "ripristina modifiche". In quanto amministratore, però, io dovrei già avere tutti i permessi necessari...quindi perché non ce li ho? Non compaio neanche nell'elenco utenti.
      Grazie infinite sin d'ora per le vostre risposte. Auguri di un felicissimo anno nuovo a tutti.
       

    • Da Metrix.
      Ciao a tutti ragazzi, sono Metrix e sono nuova.
      Ho un canale YouTube e sono alle prime armi con il mio primo MacBook Pro. Sto utilizzando iMovie e, apparentemente, non mi ha dato alcun tipo di problema. Solo che nel caricamento video su YouTube i tempi di attesa sono lunghissimi e, spesso, senza risultato, in quanto il caricamento si blocca. Ho fatto lo speedtest e la connessione è nella norma. Ho pensato sia un problema di formato o grandezza del file. Non so, magari ho salvato in maniera errata il mio filmato? Lo so che avrei dovuto esporre il problema nella 'casella' apposita ma temo nessuno mi risponda. Spero qualcuno possa aiutarmi, ve ne sarei grata.
  • Statistiche forum

    528906
    Discussioni Totali
    6332336
    Risposte Totali
  • Statistiche Utenti

    122018
    Utenti totali
    14120
    Record utenti online
    Stefania Iob
    Nuovo iscritto
    Stefania Iob
    Iscritto
  • Statistiche annunci

    105
    Annunci attivi
    18
    Domande
    0
    Recensioni
    0
    Offerte
    Ultimi Annunci
    By Boston18
    mese e 14 ore
×