web-dev-qa-db-fra.com

Comment lire les caractères caractère par caractère en Java?

Je suis habitué au c-style getchar(), mais il semble qu'il n'y ait rien de comparable pour Java. Je construis un analyseur lexical et je dois lire l'entrée par caractère.

Je sais que je peux utiliser le scanner pour numériser un jeton ou une ligne et analyser le jeton caractère par caractère, mais cela semble difficile à manier pour des chaînes couvrant plusieurs lignes. Existe-t-il un moyen d’obtenir le caractère suivant à partir du tampon d’entrée en Java ou dois-je simplement me déconnecter avec la classe Scanner?

L'entrée est un fichier, pas le clavier.

46
jergason

Utilisez Reader.read () . Une valeur de retour de -1 signifie la fin du flux; sinon, transformez en char .

Ce code lit les données de caractère dans une liste d'arguments de fichier:

public class CharacterHandler {
    //Java 7 source level
    public static void main(String[] args) throws IOException {
        // replace this with a known encoding if possible
        Charset encoding = Charset.defaultCharset();
        for (String filename : args) {
            File file = new File(filename);
            handleFile(file, encoding);
        }
    }

    private static void handleFile(File file, Charset encoding)
            throws IOException {
        try (InputStream in = new FileInputStream(file);
             Reader reader = new InputStreamReader(in, encoding);
             // buffer for efficiency
             Reader buffer = new BufferedReader(reader)) {
            handleCharacters(buffer);
        }
    }

    private static void handleCharacters(Reader reader)
            throws IOException {
        int r;
        while ((r = reader.read()) != -1) {
            char ch = (char) r;
            System.out.println("Do something with " + ch);
        }
    }
}

La mauvaise chose à propos du code ci-dessus est qu'il utilise le jeu de caractères par défaut du système. Dans la mesure du possible, préférez un codage connu (idéalement, un codage Unicode si vous avez le choix). Voir la classe Charset pour plus. (Si vous vous sentez masochiste, vous pouvez lire ce guide sur le codage de caractères .)

(Vous voudrez peut-être rechercher des caractères Unicode supplémentaires, ceux qui nécessitent le stockage de deux valeurs char. Voir la classe Character pour plus de détails; il s'agit de un cas Edge qui ne s'appliquera probablement pas aux devoirs.)

57
McDowell

En combinant les recommandations des autres utilisateurs pour spécifier un codage de caractère et mettre en mémoire tampon l'entrée, voici ce que je pense être une réponse plutôt complète.

En supposant que vous ayez un objet File représentant le fichier que vous voulez lire:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream(file),
        Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
  char character = (char) c;
  // Do something with your character
}
15
roryparle

Une autre option est de ne pas lire les choses caractère par caractère - de lire le fichier entier en mémoire. Ceci est utile si vous devez regarder les personnages plus d'une fois. Une façon triviale de le faire est:

  /** Read the contents of a file into a string buffer      */
    public static void readFile(File file, StringBuffer buf)
        throws IOException
    {
    FileReader fr = null;
    try {
      fr = new FileReader(file);
      BufferedReader br = new BufferedReader(fr);
      char[] cbuf = new char[(int) file.length()];
      br.read(cbuf);  
      buf.append(cbuf);
      br.close();
    }
    finally {
      if (fr != null) {
        fr.close();
      }
    }
}
6
David

Enveloppez votre flux d’entrée dans un lecteur mis en tampon, puis utilisez la méthode read pour lire un octet à la fois jusqu’à la fin du flux.

import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;

public class Reader {

    public static void main(String[] args) throws IOException {

        BufferedReader buffer = new BufferedReader(
                 new InputStreamReader(System.in));
        int c = 0;
        while((c = buffer.read()) != -1) {
            char character = (char) c;          
            System.out.println(character);          
        }       
    }   
}
6
pfranza

Si j'étais vous, j'utiliserais simplement un scanner et utiliserais ".nextByte ()". Vous pouvez attribuer cela à un personnage et vous êtes bon.

2
W. B. Reed

Vous avez plusieurs options si vous utilisez BufferedReader. Ce lecteur tamponné est plus rapide que Reader, vous pouvez donc l’emballer.

BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);

ceci lit la ligne dans le tableau de caractères. Vous avez des options similaires. Regardez la documentation.

1
shake

Enveloppez votre lecteur dans un BufferedReader , qui conserve un tampon permettant des lectures beaucoup plus rapides. Vous pouvez ensuite utiliser read () pour lire un seul caractère (que vous devrez transtyper). Vous pouvez également utiliser readLine () pour extraire une ligne entière, puis la scinder en caractères individuels. BufferedReader prend également en charge le marquage et le renvoi. Vous pouvez donc lire une ligne plusieurs fois si nécessaire.

En règle générale, vous souhaitez utiliser BufferedReader ou BufferedInputStream en plus du flux que vous utilisez réellement, car la mémoire tampon qu’ils gèrent rendra les lectures multiples beaucoup plus rapides.

1
James

Dans Java 5 nouvelle fonctionnalité ajoutée est la méthode Scanner qui donne la possibilité de lire les caractères entrée par caractère en Java.

par exemple; pour utiliser la méthode du scanner import Java.util.Scanner; après dans la méthode principale: define

Scanner myScanner = new Scanner (System.in); // pour le caractère lu

car rien = myScanner.findInLine ("."). charAt (0);

vous stockez n'importe quel caractère, si vous voulez plus de caractères, déclarez plus d'objet, comme tout1, tout2 ... plus d'exemple pour votre réponse, vérifiez dans votre main (copier/coller)

     import Java.util.Scanner;
     class ReverseWord  {

    public static void main(String args[]){
    Scanner myScanner=new Scanner(System.in);
    char c1,c2,c3,c4;

    c1 = myScanner.findInLine(".").charAt(0);
        c2 = myScanner.findInLine(".").charAt(0);
    c3 = myScanner.findInLine(".").charAt(0);
    c4 = myScanner.findInLine(".").charAt(0);

    System.out.print(c4);
    System.out.print(c3);
    System.out.print(c2);
    System.out.print(c1);
    System.out.println();

   }
  }
0
samir vora