J'ai un fichier .txt
avec ce contenu: "17.23;12.1;20.34;88.23523;"
. Je veux lire ce fichier en double dans une ArrayList
. Et finalement imprimer la ArrayList
(et finalement imprimer le min.et le max., Mais je ne pense pas que ce sera un problème après avoir résolu cela).
Mais je n'obtiens que la sortie "[]".
Qu'est-ce que je fais mal? Je me débat avec cela depuis plus de 15 heures embarrassantes, parcouru ici, youtube, des livres de cours ...
Mon code:
public static void main(String[] args) throws IOException { File myFile = new File("text.txt"); Scanner scan = new Scanner(myFile); ArrayList<Double> aList = new ArrayList<>(); while (scan.hasNextDouble()) { double nextInput = scan.nextDouble(); if (nextInput != 0) { break; } aList.add(nextInput); } System.out.println(alist); }
4 Réponses :
Puisque votre fichier a des nombres séparés par un point-virgule, vous ne pourrez pas les lire en utilisant scan.hasNextDouble()
par défaut. Cependant, il y a tellement de façons de le faire, par exemple
Option 1:
import java.io.File; import java.io.FileNotFoundException; import java.text.NumberFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Scanner; public class Main { public static void main(String[] args) throws FileNotFoundException, ParseException { File myFile = new File("file.txt"); Scanner scan = new Scanner(myFile); NumberFormat format = NumberFormat.getInstance(Locale.FRANCE); List<Double> aList = new ArrayList<>(); while (scan.hasNextLine()) { String nextInput = scan.nextLine(); String[] arr = nextInput.split(";"); for (String s : arr) { aList.add(format.parse(s).doubleValue()); } } System.out.println(aList); } }
Notez que puisque votre fichier a la virgule au lieu du point comme symbole décimal, vous pouvez utiliser un Locale
dans lequel il s'agit de la valeur par défaut.
[17.23, 12.1, 20.34, 88.23523]
En outre, le bloc de code suivant dans votre code entraînera la fin de la boucle après la lecture du premier nombre lui-même car le premier nombre de votre fichier n'est pas égal à zéro. Supprimez simplement ces lignes pour obtenir le résultat souhaité:
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) throws FileNotFoundException { File myFile = new File("file.txt"); Scanner scan = new Scanner(myFile); List<Double> aList = new ArrayList<>(); while (scan.hasNextLine()) { String nextInput = scan.nextLine(); String[] arr = nextInput.split(";"); for (String s : arr) { aList.add(Double.valueOf(s.replace(",", "."))); } } System.out.println(aList); } }
Option 2:
Lisez une ligne, divisez-la sur un point-virgule, remplacez la virgule par un point, analysez chaque élément du tableau résultant en Double
et stockez-le dans aList
.
Démo:
if (nextInput != 0) { break; }
Production:
scan.useLocale(Locale.FRANCE);
Une alternative pour remplacer la virgule par un point consiste à utiliser NumberFormat
comme indiqué ci-dessous:
scan.useDelimiter(";")
Tant de réponses utiles, j'ai essayé les premières démos et modifié les données pour que je comprenne. Grand merci!
Vous devez configurer votre scanner pour qu'il accepte:
;
comme délimiteur,
comme séparateur décimalLe code de travail est:
File myFile = new File("input.txt"); // Swedish locale uses ',' as a decimal separator Scanner scan = new Scanner(myFile).useDelimiter(";").useLocale(Locale.forLanguageTag("sv-SE")); ArrayList<Double> aList = new ArrayList<>(); while (scan.hasNextDouble()) { double nextInput = scan.nextDouble(); aList.add(nextInput); } System.out.println(aList);
Avec sortie [17.23, 12.1, 20.34, 88.23523]
Grande réponse, +1 de moi, même si je crois que le « Uppgift » mot dans le nom de fichier est le suédois et la Suède utilise - t ,
ainsi, changeant ainsi Locale.FRENCH
à Locale.forLanguageTag("sv-SE")
serait probablement plus précis pour la question. Même résultat, bien sûr.
Oui, bien sûr, le français n'est qu'un exemple (la locale "ru-RU" fonctionne aussi)
Un grand merci pour la réponse. Je vais vérifier cela aussi !!
Vous pouvez le faire simplement en changeant le délimiteur. Cela fonctionne en lisant à partir d'une chaîne, mais vous pouvez également le faire à partir d'un fichier. C'est à vous de mettre les valeurs dans une structure de données. Cela suppose que vos paramètres régionaux par défaut utilisent «,» comme point décimal.
17.23 12.1 20.34 88.23523
impressions
String str = "17,23;12,1;20,34;88,23523;"; Scanner scan = new Scanner(str); scan.useDelimiter("[;]+"); while(scan.hasNextDouble()) { System.out.println(scan.nextDouble()); }
La virgule est un séparateur décimal dans la question de OP, pas un séparateur de nombres
Il est peu probable que les deux ,
et ;
sont des séparateurs de valeurs. Il est beaucoup plus probable que ;
est le séparateur de valeur et que ,
est un point décimal spécifique aux paramètres régionaux, d'autant plus que le mot "Uppgift" dans le nom de fichier est suédois et que la Suède utilise ,
comme point décimal.
Eh bien, le PO n'a pas précisé cela dans la question (mais cela a du sens), alors je l'ai mis en garde dans ma réponse. Merci à vous deux!
Salut, Andreas a raison. J'ai maintenant changé cela pour la norme plus internationale! Un grand merci pour les réponses!
Scanner
fonctionne en divisant l'entrée en jetons, où les jetons sont séparés par des espaces (par défaut). Puisqu'il n'y a pas d'espaces blancs dans le texte, le premier / seul jeton est le texte entier, et puisque ce texte n'est pas une valeur double
valide, hasNextDouble()
renvoie false
.
Deux façons de résoudre ce problème:
Remplacez le séparateur de jetons par ;
:
String filename = "text.txt"; try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) { NumberFormat format = NumberFormat.getInstance(Locale.forLanguageTag("sv-SE")); for (String line; (line = in.readLine()) != null; ) { List<Double> aList = new ArrayList<>(); for (String token : line.split(";")) { double value = format.parse(token).doubleValue(); aList.add(value); } System.out.println(aList); // Prints: [17.23, 12.1, 20.34, 88.23523] } }
Lisez le fichier avec BufferedReader
et utilisez split()
:
String filename = "text.txt"; try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) { for (String line; (line = in.readLine()) != null; ) { String[] tokens = line.split(";"); // code here } }
Cela donnera désormais les jetons suivants: 17,23
, 12,1
, 20,34
, 88,23523
.
Malheureusement, aucun de ceux qui sont valides double
valeurs, car ils utilisent le formatage spécifique locale, à savoir le point décimal est un ,
et non un .
.
Ce qui signifie que si vous continuez à utiliser Scanner
, vous ne pouvez pas utiliser hasNextDouble()
et nextDouble()
, et si vous avez changé pour utiliser split()
, vous ne pouvez pas utiliser Double.parseDouble()
.
Vous devez utiliser un NumberFormat
pour analyser les formats numériques spécifiques aux paramètres régionaux. Puisque "Uppgift" a l'air suédois, nous pouvons utiliser NumberFormat.getInstance(Locale.forLanguageTag("sv-SE"))
, ou simplement NumberFormat.getInstance()
si votre locale par défaut est la Suède.
scan.useDelimiter(";");
Un grand merci (tacle :)) Andreas! J'essaierai également votre suggestion.
if (nextInput != 0) break;
pourquoi avez-vous besoin de cette ligne? À cause d'eux, votre code n'est jamais censé ajouter quelque chose à une arrayList compte tenu de votre entréePuisque votre fichier a des nombres séparés par un point-virgule, vous ne pourrez pas les lire en utilisant
scan.hasNextDouble()
par défaut. Cependant, il y a tellement de façons de le faire, par exemple en lisant une ligne sous forme de chaîne et en traitant chaque nombre à partir de celle-ci après l'avoir divisée sur le point-virgule. Une autre façon est de remplacer le délimiteur par défaut, etc.Vous avez raison nkrivenko. Oui @Arvind Kumar Avinash, je vais vérifier toutes les suggestions.