Supprimer ligne dans fichier texte [Résolu]

Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 18:26 - Dernière réponse :
Messages postés
14299
Date d'inscription
vendredi 14 mars 2003
Dernière intervention
16 novembre 2018
- 16 oct. 2010 à 13:10
Bonjour, voila j'ai un code qui doit supprimer la ligne de texte comportant le mot prédéfini. Le problème est que le code génère l'erreur :
L'index était hors limites. Il ne doit pas être négatif et doit être inférieur à la taille de la collection. Nom du paramètre : index

A mon avis le RemoveAt(i) pose problème car il supprime une ligne et cela décale le n° des lignes et au final ca les suppriment toutes.
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*txt")
                Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
                If lines.Count = 0 Then Continue For ' ne passe pas à la ligne de dessous mais remonte pour traiter le prochain fichier
                For i As Integer = 0 To lines.Count - 1
                    If lines(i).Contains("toto") Then
                        lines.RemoveAt(i)
                    End If
                Next
            Next

Qu'en pensez-vous ?

Ma LV2 c'est le Visual Basic, et toi ?
Afficher la suite 

Votre réponse

23 réponses

Meilleure réponse
Messages postés
14299
Date d'inscription
vendredi 14 mars 2003
Dernière intervention
16 novembre 2018
- 13 oct. 2010 à 21:20
3
Merci
Bonjour,

For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next
            System.IO.File.WriteAllLines(files, lines.ToArray)
        Next


Ajoute le .ToArray à la ligne d'écriture.

Merci NHenry 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Commenter la réponse de NHenry
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 19:15
0
Merci
Salut,
tu as oublié de rajouter 1 à i lorsque
tu supprime une ligne avec RemoveAt.
If lines(i).Contains("toto") Then
lines.RemoveAt(i):i+=1
End If
Commenter la réponse de raffika
Messages postés
14299
Date d'inscription
vendredi 14 mars 2003
Dernière intervention
16 novembre 2018
- 13 oct. 2010 à 19:16
0
Merci
Bonjour,

                For i As Integer = 0 To lines.Count - 1
                    If lines(i).Contains("toto") Then
                        lines.RemoveAt(i)
                    End If
                Next


Si ta ligne contient "toto", tu la retire, donc ça fait une ligne de moins.
Mais les bornes du For ne sont calculées qu'au début de la boucle, donc, une modification du nombre de lignes en cours de boucle, ne sera pas prise en compte.

2 solutions :
Soit un If pour faire un Exit For si i>Lines.count-1
soit plus fin, partir de la dernière ligne pour remonter :
For i As Integer = 0 To lines.Count - 1
deviendrait :
For i As Integer = lines.Count - 1 to 0 step -1

Commenter la réponse de NHenry
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 19:28
0
Merci
J'ai essayé la soluce de raffika, mais c'est toujours la même erreur
NHenry, j'ai essayé ta soluce n°2 qui donne la même erreur mais je comprend pas la n°1 :
Soit un If pour faire un Exit For si i>Lines.count-1

Vraiment bizard


Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 19:48
0
Merci
Ah oui ma solution ne marche pas,
mais comment ça se fait que si i est plus
grand que lines.count-1 la boucle for n'est pas stoppée ?
@aus3004 pour la première solution de NHenry, ça donnes :
For i As Integer = 0 To lines.Count - 1

If i > lines.Count - 1 Then
Exit For
End If
If lines(i).Contains("toto") Then
lines.RemoveAt(i) : i += 1
End If

Next
Pour la seconde, ça donne :
If lines(i).Contains("toto") Then
lines.RemoveAt(i) : i += 1
End If
Salutations
Commenter la réponse de raffika
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 19:50
0
Merci
PS : Euh, enleves les i+=1 ;)
Commenter la réponse de raffika
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 20:13
0
Merci
Merci raffika, j'ai essayé la soluce n°1 de NHenri mais rien ne ce passe !
Les deux documents texte ayant chacun une ligne comportant le mot prédéfini n'ont pas changés.



Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 20:15
0
Merci
Merci raffika, j'ai essayé la soluce n°1 de NHenri mais rien ne ce passe !

Je te remercie de m'avoir expliqué le code même si ca marche pas ca veut dire. lol.


Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 20:33
0
Merci
J'ai essayé les deux solutions de NHenry,
avec un fichier texte avec plusieurs lignes,
certaines contenant toto, ensuite
dans une boucle for je regarde le résultat :
for i=0 to lines.count-1
msgbox(lines(i))
next i '' donc après la modification bien sur
Qu'est ce que tu veux dire par ne marche pas ?
Quel résultat tu veux obtenir ?
Commenter la réponse de raffika
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 20:45
0
Merci
Essayes :
        For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next
            System.IO.File.WriteAllLines(TextBox1.Text, lines) '?
        Next

Salutations
Commenter la réponse de raffika
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 20:45
0
Merci
Ah, dsl j'ai peut être pas été assez claire.
Il faut que tous les fichiers texte de la boucle soient modifiés avec :
toutes les lignes comportant le mot prédéfini soient supprimées.


Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 20:58
0
Merci
Alors c'est :
        For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")

            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For

            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next
            System.IO.File.WriteAllLines(files, lines)
        Next
Commenter la réponse de raffika
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 21:00
0
Merci
Oups, une petite erreur sur le dernier lines :

Une valeur de type 'System.Collections.Generic.List(Of String)' ne peut pas être convertie en 'Tableau à 1 dimension(s) de String'.



Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
14299
Date d'inscription
vendredi 14 mars 2003
Dernière intervention
16 novembre 2018
- 13 oct. 2010 à 21:02
0
Merci
Bonjour,

Je reprend le code de Raffika (qui a utilisé la 2ième solution que j'évoquais) :
        For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next
            System.IO.File.WriteAllLines(files, lines)
        Next


Normalement, ça devrait fonctionner.

Commenter la réponse de NHenry
Messages postés
107
Date d'inscription
samedi 25 novembre 2000
Dernière intervention
4 mai 2013
- 13 oct. 2010 à 21:02
0
Merci
Bonsoir,

Tu peux tenter ceci j'ai commenté pour expliquer, mais s'il te reste des questions n'hésite pas

Dim files(), lines() As String
Dim output As New List(Of String)

Try

    ' Récupère les chemins des fichiers
    files = IO.Directory.GetFiles(TextBox1.Text, "*txt", IO.SearchOption.AllDirectories)

    For Each file In files
        ' Vide la liste
        output.Clear()

        ' Récupère les lignes du fichier
        lines = IO.File.ReadAllLines(file)

        For Each line In lines
            ' Si la ligne ne contient pas 'toto' on l'ajoute à la liste
            If Not line.Contains("toto") Then
                output.Add(line)
            End If
        Next

        ' Ne réécrit le fichier que si le contenu à changé
        ' autrement dit si son nombre de ligne a baissé
        If output.Count < lines.Length Then
            ' Je réécris dans le même fichier, si tu ne le souhaites pas
            ' pense à changer le 1er paramètre
            System.IO.File.WriteAllLines(file, output)
        End If
    Next

Catch ex As Exception
    ' En cas de problème (si un fichier est utilisé par une autre application par exemple)
    MessageBox.Show(ex.Message, "Une erreur est survenue")
End Try


Cordialement !
Commenter la réponse de Sehnsucht
Messages postés
14299
Date d'inscription
vendredi 14 mars 2003
Dernière intervention
16 novembre 2018
- 13 oct. 2010 à 21:02
0
Merci
Un peu de retard, pas grave :)
Commenter la réponse de NHenry
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 21:11
0
Merci
@aus3004 oui effectivement, pourtant le code
que je t'ai donné marche sur VB 2010...
Mais pas sur VB 2008
Je te tiens au courant...
Bonsoir
Commenter la réponse de raffika
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 21:14
0
Merci
Ouais merci les gars ca avance grave

Mais dans chacun de vos codes il y a 1 erreur.

For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next
            System.IO.File.WriteAllLines(files, lines)
        Next

Une valeur de type 'System.Collections.Generic.List(Of String)' ne peut pas être convertie en 'Tableau à 1 dimension(s) de String'.

Dim files(), lines() As String
            Dim output As New List(Of String)


            ' Récupère les chemins des fichiers
            files = IO.Directory.GetFiles(TextBox1.Text, "*txt", IO.SearchOption.AllDirectories)

            For Each file In files
                ' Vide la liste
                output.Clear()

                ' Récupère les lignes du fichier
                lines = IO.File.ReadAllLines(file)

                For Each line In lines
                    ' Si la ligne ne contient pas 'toto' on l'ajoute à la liste
                    If Not line.Contains("toto") Then
                        output.Add(line)
                    End If
                Next

                ' Ne réécrit le fichier que si le contenu à changé
                ' autrement dit si son nombre de ligne a baissé
                If output.Count < lines.Length Then
                    ' Je réécris dans le même fichier, si tu ne le souhaites pas
                    ' pense à changer le 1er paramètre
                    System.IO.File.WriteAllLines(file, output)
                End If
            Next

Une valeur de type 'System.Collections.Generic.List(Of String)' ne peut pas être convertie en 'Tableau à 1 dimension(s) de String'.




Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004
Messages postés
269
Date d'inscription
dimanche 31 mai 2009
Dernière intervention
12 mars 2011
- 13 oct. 2010 à 21:31
0
Merci
Il reste bien entendu cette dernière solution,
qui marches, selon le principe que la dernière ligne
contiendra obligatoirement un Environment.Newline
mais qui peut être modifié ...
        For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")

            Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
            If lines.Count = 0 Then Continue For

            If lines.Count = 0 Then Continue For
            For i = lines.Count - 1 To 0 Step -1
                If lines(i).Contains("toto") Then
                    lines.RemoveAt(i)
                End If
            Next

            Dim resultat As String = "" '' On crée une variable string

            For i = 0 To lines.Count - 1
                resultat &= lines(i) & Environment.NewLine 
'' on met les lignes de 'lines' une par unes suivies de 
'' Environment.Newline (retour à la ligne)
            Next

'' et on écrit le fichier selon la méthode Writealltext
'' qui écrit la string resultat dans le fichier files
            System.IO.File.WriteAllText(files, resultat)


        Next

Salutations
Commenter la réponse de raffika
Messages postés
319
Date d'inscription
jeudi 1 avril 2010
Dernière intervention
16 mars 2011
- 13 oct. 2010 à 23:03
0
Merci
J'ai pris le dernier code de NHenry, c'est impec !
@NHenry, mdr ta signature, moi je connais la Haute Autorité pour le Développement Optimal du Piratage sur Internet

Une dernière question, est-ce que cela marche avec tous les fichiers de texte à votre avis (dsl, je peux pas tester) ?

Ma LV2 c'est le Visual Basic, et toi ?
Commenter la réponse de cs_aus3004

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.