2015-07-27 12 views
6

Piszę ten program, aby zastąpić znak w n-tej pozycji ciągu w pliku tekstowym. Mój plik tekstowy składa się z następujących treści -Zastąp symbol n-tej pozycji

the quick brown fox jumped over the lazy dog 
the quick brown fox jumped over the lazy dog 
the quick brown fox jumped over the lazy dog 
the quick brown fox jumped over the lazy dog 

I tu jest wyjście kodu -

thehuick brown fox jumped over the lazy dog 

Powyższy wynik nie jest to, co chciałem. Aktualizowana jest tylko jedna linia, reszta nie znajduje się już w pliku.

Oto mój pełny kod w C#

 var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt"); 
     foreach (string currentFile in txtFiles) 
     { 
      string[] lines = File.ReadAllLines(currentFile); 
      foreach (string line in lines) 
      { 

       var theString = line; 
       var aStringBuilder = new StringBuilder(theString); 
       aStringBuilder.Remove(3, 2); 
       aStringBuilder.Insert(3, "h"); 
       theString = aStringBuilder.ToString(); 
       using (StreamWriter outfile = new StreamWriter(currentFile)) 
       { 
        outfile.Write(theString.ToString()); 
       } 

       Console.WriteLine(theString); 
       Console.ReadKey(); 

      } 
     } 

Gdzie ja poszło nie tak? Proszę pomóż!

+2

To jest prawdopodobnie ostatnia linia, ponieważ nadpisujesz plik w każdej iteracji pętli. Wypróbuj 'nowy StreamWriter (currentFile, true)' – Cole9350

+0

justs dołącza nowy ciąg na ostatniej linii – shaiToro

+0

Tak, twój napis jest dodatkowy krok o którym zapomniałem, ponieważ twój odczyt z tego samego pliku, do którego piszesz, sprawdź moją odpowiedź – Cole9350

Odpowiedz

6

Ponieważ logika mówi:

  • dla każdego pliku
    • otworzyć plik
    • dla każdego wiersza w pliku
      • proces to
      • ponownie otworzyć plik do napisania
      • wpisz wiersz

Oznacza to, że wielokrotnie nadpisuje plik z najnowszej linii. Na końcu tego pliku każdy plik zawiera tylko jedną linię: ostatnią.

Będziesz chciał zrobić coś takiego:

static void Main(string[] args) 
{ 
    foreach (string fileName in args) 
    { 
    string tempFileName = Path.GetTempFileName() ; 

    using (Stream  tmpFile = File.Open(tempFileName , FileMode.OpenOrCreate , FileAccess.Write , FileShare.None)) 
    using (StreamWriter output = new StreamWriter(tgtFile , Encoding.Default)) 
    using (Stream  srcFile = File.Open(fileName , FileMode.Open , FileAccess.ReadWrite , FileShare.None)) 
    using (StreamReader input = new StreamReader(srcFile , Encoding.Default , true)) 
    { 
     string line ; 
     while (null != (line=input.ReadLine())) 
     { 
     output.Write(line.Substring(0,3)) ; 
     output.Write('h') ; 
     output.WriteLine(line.Substring(5)) ; 
     } 
    } 

    string backupFileName = string.Format("{0}.{1:yyyy-MM-dd.HHmmss}.bak" , fileName , DateTime.Now) ; 

    File.Move(fileName  , backupFileName) ; 
    File.Move(tempFileName , fileName) ; 
    File.Delete(backupFileName) ; 

    } 
    return; 
} 

trzeba dodać trochę try/catch/finally obsługę wyjątków do czynienia z przypadkami, gdzie coś się na południe z pliku, więc można toczyć ten plik z powrotem do swojego pierwotnego stanu.

Inne opcje to

  • otwarcie pliku do odczytu.
  • slurp w całej zawartości z File.ReadAllLines() lub równoważnej
  • przekształcić linie jak uważasz
  • ponownie otworzyć oryginalny plik do zapisu
  • pluć transformowane zawartość się do oryginalnego pliku.

która prowadzi do czegoś takiego:

static void Main(string[] args) 
{ 
    foreach (string fileName in args) 
    { 
    string[] lines = File.ReadAllLines(fileName) ; 

    for (int i = 0 ; i < lines.Length ; ++i) 
    { 
     lines[i] = ApplyTransformHere(lines[i]) ; 
    } 

    File.WriteAllLines(fileName , lines) ; 

    } 

    return; 
} 
+0

Gdzie czy popełniłem błąd w moim kodzie? – shaiToro

1

Na marginesie, ale nadal związane. Czy rozważyłeś użycie Regex do zastąpienia wszystkich linii?

https://regex101.com/r/aC6cY1/1

Jak /(?<=^.{4,4})./gm

string input = "";//your sample text above 
string pattern = "(?<=^.{4,4})."; 
string replacement = "h"; 
Regex rgx = new Regex(pattern, RegexOptions.Multiline); 
string result = rgx.Replace(input, replacement); 

dotyczące problemu bym:

var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt"); 
     foreach (string currentFile in txtFiles) 
     { 
     using (StreamReader sr = new StreamReader(currentFile)) 
      { 
       string input = sr.ReadToEnd(); 
       string pattern = "(?<=^.{4,4})."; 
       string replacement = "h"; 
       Regex rgx = new Regex(pattern, RegexOptions.Multiline); 
       string result = rgx.Replace(input, replacement); 
       using (StreamWriter outfile = new StreamWriter(currentFile, append)) 
        { 
         outfile.Write(result); 
        } 
      } 
} 
+0

Mam problem z zapisywaniem do pliku – shaiToro

0

Take write-out drugiej pętli foreach, zastąp to znaczy tablicę ciągów. następnie wpisz tablicę ciągów do plików w pierwszej pętli foreach. to powinno naprawić twój problem logiczny.

+0

również, oszczędzam dużo czasu przy otwieraniu i zamykaniu plików ... – whoops1122

3

stworzyłem logiczną append na początku każdego nowego pliku, który jest ustawiony na false, więc tworzy nowy plik na pierwszej linii, a następnie ustawia dołączyć = true więc każda kolejna linia jest dołączana na

var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt"); 
foreach (string currentFile in txtFiles) 
{ 
    var append = false; 
    string[] lines = File.ReadAllLines(currentFile); 
    foreach (string line in lines) 
    { 
     var theString = line; 
     var aStringBuilder = new StringBuilder(theString); 
     aStringBuilder.Remove(3, 2); 
     aStringBuilder.Insert(3, "h"); 
     theString = aStringBuilder.ToString(); 
     using (StreamWriter outfile = new StreamWriter(currentFile, append)) 
     { 
      outfile.Write(theString.ToString() + Environment.NewLine); 
     } 
     append = true; 
    } 
}