web-dev-qa-db-fra.com

Pourquoi hasNext () est-il faux, alors que hasNextLine () est True?

Question

Comment se fait-il que pour un objet d'analyse, la méthode hasNextLine() renvoie true alors que la méthode hasNext() renvoie false?

Remarque: En fonction du fichier d'entrée, la méthode hasNext() renvoie le résultat comme prévu. hasNextLine() ne semble pas renvoyer le résultat correct.

Code

Voici le code que je lance qui crée les résultats ci-dessous:

public void ScannerTest(Reader fileReaderObject){
    Scanner scannerObj = new Scanner(fileReaderObject);

    for(int i = 1; scannerObj.hasNext(); i++){
        System.out.println(i + ": " + scannerObj.next());
        System.out.println("Has next line: " + scannerObj.hasNextLine());
        System.out.println("Has next: " + scannerObj.hasNext());
    }
    System.out.println();

    scannerObj.close();
}

Fichier d'entrée

Voici le contenu réel du fichier que je transmets à ce scanner:

a   3   9
b   3   6
c   3   3
d   2   8
e   2   5
f   2   2
g   1   7
h   1   4
i   1   1

Résultat

Ce qui suit est la fin de ce qui est imprimé dans la console lorsque je lance mon code, et inclut la partie que je ne peux pas comprendre:

25: i
Has next line: true
Has next: true
26: 1
Has next line: true
Has next: true
27: 1
Has next line: true
Has next: false
61
DRich

Vous avez une nouvelle ligne supplémentaire à la fin de votre fichier.

  • hasNextLine() vérifie s'il existe une autre variable linePattern dans le tampon.
  • hasNext() vérifie s'il existe un jeton analysable dans la mémoire tampon, séparé par le délimiteur du scanner.

Puisque le délimiteur du scanner est un espace et que la linePattern est également un espace blanc, il est possible qu'il y ait une linePattern dans le tampon mais pas de jetons analysables.

Généralement, le moyen le plus courant de traiter ce problème consiste à appeler toujours nextLine() après avoir analysé tous les jetons (par exemple, des nombres) dans chaque ligne de votre texte. Vous devez faire cela lorsque vous utilisez Scanner lors de la lecture de l'entrée d'un utilisateur à partir de System.in. Pour faire avancer le scanner au-delà de ce délimiteur d'espaces, vous devez utiliser scanner.nextLine() pour effacer le délimiteur de ligne. Voir: Utilisation de scanner.nextLine ()


Appendice:

LinePattern est défini comme étant un Pattern qui correspond à ceci:

private static final String LINE_SEPARATOR_PATTERN =
                                       "\r\n|[\n\r\u2028\u2029\u0085]";
private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";

Le délimiteur de jeton par défaut est Pattern:

private static Pattern WHITESPACE_PATTERN = Pattern.compile(
                                            "\\p{javaWhitespace}+");
58
durron597

La raison en est que hasNext() vérifie s'il y a plus de caractères non-blancs disponibles. hasNextLine() vérifie si une autre ligne de texte est disponible. Votre fichier texte a probablement une nouvelle ligne à la fin, donc il a une autre ligne mais plus de caractères qui ne sont pas des espaces.

De nombreux éditeurs de texte ajoutent automatiquement une nouvelle ligne à la fin d'un fichier s'il n'en existe pas déjà.

En d'autres termes, votre fichier d'entrée n'est pas ceci (les numéros sont des numéros de ligne):

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5

C'est en fait ceci:

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5
6. 
15
Daniel Centore

Réponse courte

Vous avez une ligne vide à la fin du fichier.


Raison de la ligne vide

Si vous prenez votre contenu et que vous l'enregistrez par exemple dans un fichier txt, certains éditeurs ajouteront une nouvelle ligne vide à votre fichier.

Les éditeurs se comportent de cette façon, car cela fait partie du POSIX standard:

3.206 Ligne 

Une séquence de zéro ou plusieurs non-caractères plus un caractère de fin.

Ce sujet a été discuté dans ce fil de discussion .


Documentation Java Scanner

Voici la documentation de la classe Java 8 Scanner class .

hasNext()

Renvoie true si ce scanner a un autre jeton en entrée.


hasNextLine()

Retourne vrai s'il y a une autre ligne dans l'entrée de ce scanner.


Raison du comportement du code Java

En raison des faits décrits ci-dessus, hasNextLine() retournera true, mais hasNext() ne trouvera rien, qu'il puisse reconnaître comme Token et renvoie donc false.

Pour plus d'informations, voir durron597 post.

14
kamwo

Le concept de base de hasNext () et hasNextLine () est

hasNextLine : - Retourne vrai s'il y a une autre ligne dans l'entrée de ce scanner. Cette méthode peut bloquer en attendant une entrée. Le scanner ne dépasse aucune entrée.

Retourne: True si et seulement si ce scanner a une autre ligne d'entrée Lance: IllegalStateException - si ce scanner est fermé

hasNext

Retourne vrai si le prochain jeton complet correspond au modèle spécifié.

Un jeton complet est préfixé et postfixé par une entrée correspondant au modèle de délimiteur. Cette méthode peut bloquer en attendant une entrée. Le scanner ne dépasse aucune entrée.

Paramètres: Pattern - le motif à rechercher

Retourne: True si et seulement si ce scanner a un autre jeton correspondant au modèle spécifié

Depuis votre dernière entrée disant true pour nextLine () car Un appel à scan.nextLine (); renvoie le jeton suivant. Il est important de noter que le scanner renvoie un espace et une lettre, car il lit depuis la fin du dernier jeton jusqu'au début de la ligne suivante.

0
Manpreet gujral