IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

String avec retour à la ligne tous les '100' caractères


Sujet :

avec Java

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut String avec retour à la ligne tous les '100' caractères
    Bonjour,


    Je suis en train de développer une petite fonction qui, dans une variable String, fait un saut de ligne tous le 100 caractères en essayant de ne pas couper les mots. C'est à dire que s'il faut faire un retour à la ligne au caractère 99 pour ne pas se retrouver avec un début de mot en fin de ligne et sa suite à la ligne d'après, il faut gérer cela.


    Pour l'instant j'ai réussi à faire une fonction qui marche mais j'aimerais avoir votre avis, pour savoir si on peut l'améliorer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static String formatString(String lines){
        String maChaine=lines;
        int NB_MAX=100, i=0, index =-1;
     
        while(i+NB_MAX < lines.length()-1){
            index = maChaine.substring(i, i+NB_MAX).lastIndexOf(' ');
     
            if(index != -1)
                maChaine = maChaine.substring(0, (index+i)+1) + '\n' + maChaine.substring((index+i)+1);
     
            else
                maChaine = maChaine.substring(0, i+1) + '\n' + maChaine.substring(i+1);
     
     
            i+= index+1;
        }
     
     
        return maChaine;
      }

    En vous remerciant par avance,

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Il serait sans doute un peu plus simple et un peu plus propre de construire la chaîne dans un StringBuilder au lieu de le faire à coups de +

    Pour déterminer où couper les lignes, tu pourrais utiliser lastIndexOf() sur tout le restant de la string, mais en commençant à l'extrême limite autorisée, avec lastIndexOf(int ch, int fromIndex).
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut
    Bonjour et merci de votre réponse.

    Si je comprends bien, je dois créer une variable StringBuilder et construire ma chaîne grâce à la méthode append()?

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ce serait plus efficace et plus facile à lire, oui.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut
    Voici mon nouveau Code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    public static String formatString(String lines){
     
        int NB_MAX=100, i=0, index;
        StringBuilder maChaine = new StringBuilder();
     
        while(i+NB_MAX < lines.length()-1){
            //On cherche le dernier index du caractère 'espace'
            index = lines.substring(i, i+NB_MAX).lastIndexOf(' ');
            //Si le caractère a été trouvé
            if(index !=-1){
                //On concaténe la sous-chaine au StringBuilder
                maChaine.append(lines.substring(i, i+index));
                //On met à jour la taille de sous-chaine traitée
                i += index+1;
            }
            //Sinon
            else{
                //On concaténe une sous-chaine contenant 'NB_MAX' caractères au StringBuilder
                maChaine.append(lines.substring(i, i+NB_MAX));
                //On met à jour la taille de sous-chaine traitée 
                i += NB_MAX;
            }
            //On concaténe le caractère 'retour chariot' au StringBuilder
            maChaine.append('\n');
        }
     
        //On renvoie la chaine obtenue
        return maChaine.toString();
      }
    Merci de me donner vos impressions.


    EDIT: Il faut aussi rajouter un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maChaine.append(lines.substring(i, lines.length()));
    après le while pour qu'il concatène la fin de la chaine.

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Pas mal. Voici ma tentative :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // en principe, même taille que la chaîne originale. Autant pré-réserver.
    StringBuilder maChaine = new StringBuilder(lines.length());
    int index = 0;
     
    while(index < lines.length()) {
      int spaceIndex = lines.lastIndexOf(' ', index + NB_MAX);
     
      if(spaceIndex < index) { // inclut < 0, donc espace non trouvé : on a fini
        maChaine.append(lines.substring(index));
        index = lines.length();
      } else {
        maChaine.append(lines.substring(index, spaceIndex));
        maChaine.append('\n');
        index = spaceIndex + 1;
      }
    }
    Ça évite de faire des substring() à répétition.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Pas mal. Voici ma tentative :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // en principe, même taille que la chaîne originale. Autant pré-réserver.
    StringBuilder maChaine = new StringBuilder(lines.length());
    int index = 0;
     
    while(index < lines.length()) {
      int spaceIndex = lines.lastIndexOf(' ', index + NB_MAX);
     
      if(spaceIndex < index) { // inclut < 0, donc espace non trouvé : on a fini
        maChaine.append(lines.substring(index));
        index = lines.length();
      } else {
        maChaine.append(lines.substring(index, spaceIndex));
        maChaine.append('\n');
        index = spaceIndex + 1;
      }
    }
    Ça évite de faire des substring() à répétition.
    Ne faut-il pas utiliser indexOf plutot que lastIndexOf ?

    Cette méthode est un peu plus rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     public static String formatString(String lines) {
        final int NB_MAX = 100;
        StringBuilder maChaine = new StringBuilder(lines);
        int index = 0;
     
        do {
          index = maChaine.indexOf(" ", index + NB_MAX);
          if (index < 0) {
            break;
          }
          maChaine.setCharAt(index, '\n');
        }
        while (true);
        return maChaine.toString();
     
      }

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Fred_34 Voir le message
    Ne faut-il pas utiliser indexOf plutot que lastIndexOf ?
    ?

    Mais... Le but est de découper en lignes qui ne dépassent pas les 100 caractères. Dans ce cas il faut chercher de la fin vers le début, non ?
    On pourrait faire une recherche incrémentale à la limite, mais ce serait plus compliqué et pas spécialement plus efficace.

    Citation Envoyé par Fred_34 Voir le message
    Cette méthode est un peu plus rapide :
    Bien vu. Après tout il ne s'agit que de remplacer quelques caractères dans la chaîne. Ce sera plus efficace de faire exactement ça.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Mais... Le but est de découper en lignes qui ne dépassent pas les 100 caractères. Dans ce cas il faut chercher de la fin vers le début, non ?
    Oups...
    Effectivement ta méthode fait des lignes de 100 ou moins. La mienne fait des lignes de 100 ou plus

    Pour la peine, je t'ai trouvé un bug :
    Si au milieu d'un document il y a une ligne de 100 caractères sans espace, ta méthode s’arrête.

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Fred_34 Voir le message
    Pour la peine, je t'ai trouvé un bug :
    Si au milieu d'un document il y a une ligne de 100 caractères sans espace, ta méthode s’arrête.
    Je sais, il vaudrait mieux lancer une Exception, j'imagine. Mais en réalité il faudrait voir quel est le comportement attendu dans ce cas.
    Le problème présuppose beaucoup que c'est un cas qui n'arrive pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut
    Bonjour et merci à vous.

    Citation Envoyé par Fred_34 Voir le message
    Cette méthode est un peu plus rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     public static String formatString(String lines) {
        final int NB_MAX = 100;
        StringBuilder maChaine = new StringBuilder(lines);
        int index = 0;
     
        do {
          index = maChaine.indexOf(" ", index + NB_MAX);
          if (index < 0) {
            break;
          }
          maChaine.setCharAt(index, '\n');
        }
        while (true);
        return maChaine.toString();
     
      }
    Je ne savais pas qu'on pouvait utiliser un break dans un do-while tiens.
    Par contre j'ai l'impression que s'il n'y a pas d'espaces, on pourrait tout à fait se retrouver avec une seule ligne, je me trompe?
    Je ne sais pas si vous l'aviez remarqué mais justement j'ai essayé de gérer ce cas là, et dans cette éventualité je ne me pose pas de questions, je coupe à 'NB_MAX' caractères. Et à ce moment là, pourrions nous faire ceci?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static String formatString(String lines) {
        final int NB_MAX = 100;
        StringBuilder maChaine = new StringBuilder(lines);
        int index = 0,indexTemp=0;
     
        while (index+NB_MAX < maChaine.lenght()-1){
            index = maChaine.indexOf(" ", index + NB_MAX);
            if (index < 0) {
                index = indexTemp + NB_MAX;
                maChaine.insert(index+1,'\n');
            }
            else
                maChaine.setCharAt(index, '\n');
     
            indexTemp = index;
        }
     
        return maChaine.toString();
     
      }
    Bien évidemment cela ne change pas le fait que cette méthode permet d'obtenir des lignes>=100 caractères.



    Quand à votre méthode thelvin, Fred_34 a soulevé les 2 questions que justement je me posais:

    •Utiliser indexOf() plutôt que lastIndexOf(). Si on utilise lastIndexOf(char,fromIndex) le dernier mot se retrouvera forcément tout seul non?

    •En cas d'une chaine de plus de 100 caractères la méthode s'arrête.



    Cordialement,

  12. #12
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par Portugues13 Voir le message

    Quand à votre méthode thelvin, Fred_34 a soulevé les 2 questions que justement je me posais:

    •Utiliser indexOf() plutôt que lastIndexOf(). Si on utilise lastIndexOf(char,fromIndex) le dernier mot se retrouvera forcément tout seul non?
    Il faut juste modifier le while

    Citation Envoyé par Portugues13 Voir le message
    •En cas d'une chaine de plus de 100 caractères la méthode s'arrête.
    Il ne faut plus s’arrêter mais couper lorsqu'on ne trouve pas d'espace.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    public static String formatString(String lines) {
        int NB_MAX = 100;
        // en principe, même taille que la chaîne originale. Autant pré-réserver.
        StringBuilder maChaine = new StringBuilder(lines.length());
        int index = 0;
     
        while (index + NB_MAX < lines.length()) {
          int spaceIndex = lines.lastIndexOf(' ', index + NB_MAX);
     
          if (spaceIndex < index) {
            maChaine.append(lines.substring(index, index + NB_MAX));
            maChaine.append('\n');
            index += NB_MAX;
          }
          else {
            maChaine.append(lines.substring(index, spaceIndex));
            maChaine.append('\n');
            index = spaceIndex + 1;
          }
        }
        return maChaine.toString();
     
      }

  13. #13
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Portugues13 Voir le message
    •Utiliser indexOf() plutôt que lastIndexOf(). Si on utilise lastIndexOf(char,fromIndex) le dernier mot se retrouvera forcément tout seul non?
    J'ai effectivement un bug qui met toujours le dernier mot tout seul, mais ce n'est pas à cause de lastIndexOf(), c'est juste que je n'y ai pas pensé.

    Le but est de faire des lignes qui ne dépassent pas 100 caractères, non ?
    Dans ce cas, on ne peut pas chercher au-delà du 100e caractère, il faut chercher avant le 100e caractère. Donc lastIndexOf().

    Citation Envoyé par Portugues13 Voir le message
    •En cas d'une chaine de plus de 100 caractères la méthode s'arrête.
    Parce qu'on a pas décidé ce qu'il fallait faire dans ce cas. C'est un cas aux limites, ce sera forcément moins élégant de le gérer.

    Voici comment je préférerais faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Tant que ce qui reste est plus grand que la taille max d'une ligne
    while(maChaine.length() - index > NB_MAX) {
      int spaceIndex = maChaine.lastIndexOf(" ", index + NB_MAX);
      if(spaceIndex < index) { // pas trouvé d'espace pour couper. On coupe au max.
        maChaine.insert(index + NB_MAX, '\n');
        index += NB_MAX + 1;
      } else {
        maChaine.setCharAt(spaceIndex, '\n');
        index = spaceIndex + 1;
      }
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut
    Merci.

    Par contre, ôtez moi d'un doute.
    Lorsqu'on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maChaine.lastIndexOf(' ',index+NB_MAX)
    Est-ce que ça va chercher le caractère 'espace' entre les index 0 et 'index+NB_MAX' ou c'est entre 'index+NB_MAX' et maChaine.lenght()? (ou encore autre chose?...)
    Parce que justement je ne suis pas sûr d'avoir bien compris le fonctionnement de cette méthode et ça m'empêche de bien comprendre votre code.

    Cordialement,

  15. #15
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Portugues13 Voir le message
    Par contre, ôtez moi d'un doute.
    Lorsqu'on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maChaine.lastIndexOf(' ',index+NB_MAX)
    Est-ce que ça va chercher le caractère 'espace' entre les index 0 et 'index+NB_MAX' ou c'est entre 'index+NB_MAX' et maChaine.lenght()? (ou encore autre chose?...)
    Parce que justement je ne suis pas sûr d'avoir bien compris le fonctionnement de cette méthode et ça m'empêche de bien comprendre votre code.
    Entre 'index+NB_MAX' et 0.

    Ça s'appelle "last index of". Et sa JavaDoc est ici.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #16
    Membre régulier
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2012
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 57
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Entre 'index+NB_MAX' et 0.

    Ça s'appelle "last index of". Et sa JavaDoc est ici.
    J'avais lu la JavaDoc mais justement, tel que je l'avais compris, 'index+NB_MAX' c'était l'index de départ, en d'autres termes on prenait un substring entre 'index+NB_MAX' et la fin de la chaine.

    Enfin bon j'ai la solution qu'il me fallait et je remercie les personnes qui ont participé à ce sujet!

    Je marque comme Résolu.

  17. #17
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    L'index de départ, oui, mais pour aller vers le début, pas vers la fin. J'ai du mal à croire qu'on puisse comprendre autre chose en lisant la JavaDoc. Déjà que rien qu'avec le nom et en raisonnant par complétude avec les indexOf() -_-°...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [KSH] ajouter des saut de lignes tous les 200 caractères dans un fichier
    Par twixi dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 09/10/2012, 15h58
  2. saut de ligne tous les n caractère
    Par bigs3232 dans le forum Langage
    Réponses: 2
    Dernier message: 07/01/2012, 13h41
  3. Concatenation string avec retour a la ligne
    Par X-Nem dans le forum SAP
    Réponses: 1
    Dernier message: 25/08/2008, 16h09
  4. Réponses: 2
    Dernier message: 16/08/2006, 14h47
  5. [CSS] espace dans les li avec retour à la ligne
    Par grinder59 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 04/07/2006, 11h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo