web-dev-qa-db-fra.com

Imprimer avec "\ t" (onglets) n'entraîne pas d'alignement de colonnes

J'ai un problème très étrange. Après avoir écrit ceci:

for (File f : currentFile.listFiles()) {            
    if  (f.isDirectory()){
        System.out.println(f.getName()+"\t"+"Dir\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
    }
    else{
        System.out.println(f.getName()+"\t"+"File\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
    }

Je vois ceci imprimé:

see.txt File    rw  267642728448
see1.txt    File    rw  267642728456
see2.txt    File    rw  267642728448

Pourquoi y a-t-il un problème avec les onglets?

28
Unknown user

En me basant sur cette question , j’utilise le code suivant pour mettre en retrait mes messages:

String prefix1 = "short text:";
String prefix2 = "looooooooooooooong text:";
String msg = "indented";
/*
 * The second string begins after 40 characters. The dash means that the
 * first string is left-justified.
 */
String format = "%-40s%s%n";
System.out.printf(format, prefix1, msg);
System.out.printf(format, prefix2, msg);

C'est la sortie:

 texte court: en retrait 
 looooooooooooooong texte: en retrait 
32
Matthias Braun

Le "problème" des onglets est qu’ils indentent le texte sur des positions d’onglet fixes, généralement des multiples de 4 ou 8 caractères (selon la console ou l’éditeur les affichant). Votre premier nom de fichier est composé de 7 caractères, de sorte que la prochaine tabulation après la fin de celle-ci se trouve à la position 8. Toutefois, les noms de fichiers suivants ont une longueur de 8 caractères. La prochaine tabulation est donc à la position 12.

Si vous voulez vous assurer que les colonnes sont bien mises en retrait à la même position, vous devez prendre en compte la longueur réelle des colonnes précédentes et modifier le nombre d'onglets suivants ou utiliser le pavé avec le nombre d'espaces requis. Ce dernier peut être réalisé en utilisant par exemple System.out.printf avec une spécification de format appropriée (par exemple, "%1$13s" spécifie une largeur minimale de 13 caractères pour afficher le premier argument sous forme de chaîne).

23
Péter Török

La longueur du texte que vous fournissez dans chaque ligne est différente, tel est le problème. Par conséquent, si le deuxième mot est trop long (see2.txt Est long de 8 caractères, ce qui correspond à une seule longueur de tabulation), il est affiché. un onglet qui va au point de tabulation suivant. Une façon de le résoudre est d’ajouter par programmation un pad au texte f.getName() afin que chaque texte généré: see.txt Ou see2.txt Ait la même longueur (par exemple see.txt_ et see2.txt) afin que chaque onglet passe automatiquement au même point de tabulation.

Si vous développez avec JDK 1.5, vous pouvez résoudre ce problème en utilisant Java.util.Formatter :

String format = "%-20s %5d\n";
System.out.format(format, "test", 1);
System.out.format(format, "test2", 20);
System.out.format(format, "test3", 5000);

cet exemple vous donnera cette empreinte:

test                     1
test2                   20
test3                 5000
6
madx

Dans la suite des commentaires de Péter et duncan, j’utilise normalement une méthode de remplissage rapide, quelque chose comme:

public String rpad(String inStr, int finalLength)
{
    return (inStr + "                          " // typically a sufficient length spaces string.
        ).substring(0, finalLength);
}

de même, vous pouvez aussi avoir une lpad()

5
d-live

Comme mentionné par d'autres personnes, la longueur variable de la chaîne est le problème.

Plutôt que de réinventer la roue, Apache Commons propose une solution agréable et propre à StringUtils.

StringUtils.rightPad("String to extend",100); //100 is the length you want to pad out to.
2
jayb0b

Le problème est la longueur des noms de fichiers. Le premier nom de fichier ne fait que 7 caractères, donc la tabulation apparaît au caractère 8 (faire une tabulation tous les 4 caractères). Cependant, les noms de fichiers suivants ont une longueur de 8 caractères, aussi le prochain onglet ne sera-t-il pas jusqu'au caractère 12. Et si vous avez un nom de fichier de plus de 11 caractères, vous rencontrez le même problème.

2
duncan

Vous pouvez utiliser cet exemple pour gérer votre problème:

System.out.printf( "%-15s %15s %n", "name", "lastname");
System.out.printf( "%-15s %15s %n", "Bill", "Smith");

Vous pouvez jouer avec le "%" jusqu'à trouver le bon alignement pour satisfaire vos besoins

1
Rolando F

Vous pouvez également ajouter une chaîne à la longueur requise à l’aide de la méthode de Guava Strings.padEnd (Entrée de chaîne, int minLength, char padding)

1
Kurru