zrubi zrubi - 3 months ago 8
C# Question

Replace found line in text document

I got this code, which finds doubles with odd indexes to replace all with "X" except first one with odd index but keeps all doubles with even indexes. Question is how to replace found line in text document. This way I got result which must be replaced but how to overwrite lines in text document

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
const string FILENAME = "test.txt";
static void Main(string[] args)
{
List<string> uniqueOddLines = new List<string>();
List<string> lines = new List<string>();
string inputLine = "X";
StreamReader reader = new StreamReader(FILENAME);
int index = 0;
while ((inputLine = reader.ReadLine()) != null)
{
inputLine = inputLine.Trim();
if (++index % 2 == 0)
{
lines.Add(inputLine);
}
else
{
if (uniqueOddLines.Contains(inputLine))
{
lines.Add(string.Format("Rewrite line {0}", index));
}
else
{
uniqueOddLines.Add(inputLine);
lines.Add(inputLine);
}
}
}
foreach (string line in lines)
{
Console.WriteLine(line);
}
Console.ReadLine();
}
}
}


For example content in text document is:

row1
row2
row3
row4
row5
row6
row3
row8
row9
row3
row11
row3
row3
row3


work of given code:

01. row1
02. row2
03. row3 <- keep row with odd index because it is first in order
04. row4
05. row5
06. row6
07. row3 <- rewrite this double because it is not the first one with odd index
08. row8
09. row9
10. row3 <- keep this double, because row index is even number
11. row11
12. row3 <- keep this double, because row index is even number
13. row3 <- rewrite this double because it is not the first one with odd index
14. row3 <- keep this double, because row index is even number


And here is desired result, same as above, but I want it in text document:

row1
row2
row3
row4
row5
row6
X
row8
row9
row3
row11
row3
X
row3

Answer

I suggest using Linq: ReadLines will return the file lines and Select is convenient to implement the logic within:

const string FILENAME = "test.txt";

// Side effect (adding into the set while selecting) is very convenient in the context,
// but should be implemented with care 
HashSet<String> appeared = new HashSet<String>();

var result = File
  .ReadLines(FILENAME)
   // index % 2 == 0 since index is zero-based
  .Select((line, index) => !appeared.Add(line.Trim()) && (index % 2 == 0) 
     ? "X"
     : line)
  .ToList(); // materialization, in case you want both Console and File 

foreach (var line in result)
  Console.WriteLine(line);

Console.ReadLine();

In case you want to write the lines back to file as well as onto console:

File.WriteAllLines(FILENAME, result);
Comments