Supprimer ligne dans fichier texte [Résolu]

cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 18:26 - Dernière réponse : NHenry 14171 Messages postés vendredi 14 mars 2003Date d'inscription 17 mai 2018 Dernière intervention
- 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

NHenry 14171 Messages postés vendredi 14 mars 2003Date d'inscription 17 mai 2018 Dernière intervention - 13 oct. 2010 à 21:20
+3
Utile
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.

Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de NHenry
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 19:15
0
Utile
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
NHenry 14171 Messages postés vendredi 14 mars 2003Date d'inscription 17 mai 2018 Dernière intervention - 13 oct. 2010 à 19:16
0
Utile
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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 19:28
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 19:48
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 19:50
0
Utile
PS : Euh, enleves les i+=1 ;)
Commenter la réponse de raffika
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 20:13
0
Utile
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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 20:15
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 20:33
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 20:45
0
Utile
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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 20:45
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 20:58
0
Utile
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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 21:00
0
Utile
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
NHenry 14171 Messages postés vendredi 14 mars 2003Date d'inscription 17 mai 2018 Dernière intervention - 13 oct. 2010 à 21:02
0
Utile
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
Sehnsucht 107 Messages postés samedi 25 novembre 2000Date d'inscription 4 mai 2013 Dernière intervention - 13 oct. 2010 à 21:02
0
Utile
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
NHenry 14171 Messages postés vendredi 14 mars 2003Date d'inscription 17 mai 2018 Dernière intervention - 13 oct. 2010 à 21:02
0
Utile
Un peu de retard, pas grave :)
Commenter la réponse de NHenry
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 21:11
0
Utile
@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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 21:14
0
Utile
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
raffika 269 Messages postés dimanche 31 mai 2009Date d'inscription 12 mars 2011 Dernière intervention - 13 oct. 2010 à 21:31
0
Utile
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
cs_aus3004 319 Messages postés jeudi 1 avril 2010Date d'inscription 16 mars 2011 Dernière intervention - 13 oct. 2010 à 23:03
0
Utile
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.

Supprimer ligne dans fichier texte - page 2