I have looked all over for the answer to this, but I can't find it anywhere. I need to be able to clear a line from a txt file by the last integer in the line (the ID number), but I have no idea how to do that. Please help? Basically I was thinking that I need to find the last integer, and if it does not equal to the input, then it would move to the next line until it finds the right integer. Then that line is cleared. Here is some of my code that obviously doesn't work:
public static void TicID(CommandArgs args)
{
if (args.Parameters.Count == 1)
{
if (i == 1)
{
try
{
string idToDelete = args.Parameters[0];
StreamReader idreader = new StreamReader("Tickets.txt");
StreamWriter iddeleter = new StreamWriter("Tickets.txt");
string id = Convert.ToString(idreader.Read());
string line = null;
while (idreader.Peek() >= 0)
{
if (String.Compare(id, idToDelete) == 0)
{
iddeleter.WriteLine(line);
}
else
{
idreader.ReadLine();
}
}
}
The most straightforward way to delete lines is to write the lines that should not be deleted:
var idToDelete = "1";
var path = #"C:\Temp\Test.txt";
var lines = File.ReadAllLines(path);
using (var writer = new StreamWriter(path, false)) {
for (var i = 0; i < lines.Length; i++) {
var line = lines[i];
//assuming it's a CSV file
var cols = line.Split(',');
var id = cols[cols.Length - 1];
if (id != idToDelete) {
writer.WriteLine(line);
}
}
}
This is the LINQ-way:
var lines = from line in File.ReadAllLines(path)
let cols = line.Split(',')
let id = cols[cols.Length - 1]
where id != idToDelete
select line;
File.WriteAllLines(path, lines);
Create a StreamReader object and read line by line into a string array or something like that using StreamReader's instance method ReadLine() and now find your line of choice in your text array and delete it.
Important note:
do { /*see description above*/ } while (streamReader.Peak() != -1);
Related
That code makes filter on the files with the regular expression, and to shape the results. But how can I get a line number of each matches in the file?
I have no idea how to do it...
Please help me
class QueryWithRegEx
enter code here
IEnumerable<System.IO.FileInfo> fileList = GetFiles(startFolder);
System.Text.RegularExpressions.Regex searchTerm =
new System.Text.RegularExpressions.Regex(#"Visual (Basic|C#|C\+\+|Studio)");
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileText = System.IO.File.ReadAllText(file.FullName)
let matches = searchTerm.Matches(fileText)
where matches.Count > 0
select new
{
name = file.FullName,
matchedValues = from System.Text.RegularExpressions.Match match in matches
select match.Value
};
Console.WriteLine("The term \"{0}\" was found in:", searchTerm.ToString());
foreach (var v in queryMatchingFiles)
{
string s = v.name.Substring(startFolder.Length - 1);
Console.WriteLine(s);
foreach (var v2 in v.matchedValues)
{
Console.WriteLine(" " + v2);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
static IEnumerable<System.IO.FileInfo> GetFiles(string path)
{
...}
Give this a go:
var queryMatchingFiles =
from file in Directory.GetFiles(startFolder)
let fi = new FileInfo(file)
where fi.Extension == ".htm"
from line in File.ReadLines(file).Select((text, index) => (text, index))
let match = searchTerm.Match(line.text)
where match.Success
select new
{
name = file,
line = line.text,
number = line.index + 1
};
You can Understand from this example:
Read lines number 3 from string
string line = File.ReadLines(FileName).Skip(14).Take(1).First();
Read text from a certain line number from string
string GetLine(string text, int lineNo)
{
string[] lines = text.Replace("\r","").Split('\n');
return lines.Length >= lineNo ? lines[lineNo-1] : null;
}
Retrieving the line number from a Regex match can be tricky, I'd use the following approach:
private static void FindMatches(string startFolder)
{
var searchTerm = new Regex(#"Visual (Basic|C#|C\+\+|Studio)");
foreach (var file in Directory.GetFiles(startFolder, "*.htm"))
{
using (var reader = new StreamReader(file))
{
int lineNumber = 1;
string lineText;
while ((lineText = reader.ReadLine()) != null)
{
foreach (var match in searchTerm.Matches(lineText).Cast<Match>())
{
Console.WriteLine($"Match found: <{match.Value}> in file <{file}>, line <{lineNumber}>");
}
lineNumber++;
}
}
}
}
I have text document contains line name and next line its value.
I wrote this but I can't rewrite the line after replaced it.
public bool checkExist(string catName)
{
int saveValue = 0;
bool found = false;
foreach (string line in File.ReadLines(Form1.INCOMES_EXPENSE_VALUES_MONTH + Form1.CurrentMonth.ToString() + ".txt"/*get the file that I need to search in*/))
{
if (line == catName)
{
found = true;
index++;
continue;
}
else
index++;
if (found)
{
saveValue = int.Parse(line);
saveValue += int.Parse(txtValue.Text);
line.Replace(line, saveValue.ToString());
found = false;
return true;
}
}
return false;
}
I suggest implementing a simple Finite State Machine; we have two states here: line before is catName (found == true) or not (found == false):
private static IEnumerable<string> UpdatedCat(string file, string catName, int add) {
bool found = false;
// AllLines: materialization if you want to write the modified data
// back to the same file
foreach (string line in File.ReadAllLines(file)) {
if (found) {
found = false;
int value = int.Parse(line);
yield return $"{value + add}";
}
else {
yield return line;
// Trim() : to be on the safe side if line has leading / trailing spaces
found = (line.Trim() == catName);
}
}
}
Then you can put
string file = $"{Form1.INCOMES_EXPENSE_VALUES_MONTH}{Form1.CurrentMonth}.txt";
File.WriteAllLines(file, UpdatedCat(file, "MyCat", int.Parse(txtValue.Text)));
In fact you can only modify a file (line) with write back the entire file (lines),
example:
Read entire file lines > modify the line in temp > write back modified entire lines to file
To change line in file
ChangeLine(#"This is modified line", #"C:\MyFile.txt", 6);
public void ChangeLine(string newText, string fullPath, int lineToEdit)
{
// Read entire file lines
string[] lines = File.ReadAllLines(fullPath);
// Edit the line
lines[lineToEdit - 1] = newText;
// Write back to file
File.WriteAllLines(fullPath, lines, Encoding.UTF8);
}
To delete line in file
DeleteLine(#"C:\MyFile.txt", 6);
public void DeleteLine(string fullPath, int lineToDelete)
{
string line = null;
int line_number = 0;
var newstr = new StringBuilder();
// Read entire file lines
using (StreamReader reader = new StreamReader(fullPath))
{
while ((line = reader.ReadLine()) != null)
{
line_number++;
// Exclude deleted line
if (line_number == lineToDelete)
continue;
newstr.AppendLine(line);
}
}
// Write back to file
using (StreamWriter sw = new System.IO.StreamWriter(
new FileStream(fullPath, FileMode.Create), Encoding.UTF8))
{
sw.Write(newstr.ToString().TrimEnd()); // Remove blank line at end
}
}
To insert line at line index in file
InsertLineAtIndex(#"C:\MyFile.txt", 6, #"This is new line");
public static void InsertLineAtIndex(
string fullPath,
int atIndex,
string lineToAdd,
bool toBelow = false)
{
// Read entire file lines
var txtLines = File.ReadAllLines(fullPath).ToList();
// Specify insert location
int index = toBelow ? (atIndex - 1) + 1 : (atIndex - 1);
if (index > 0)
{
// Insert the line
txtLines.Insert(index, lineToAdd);
// Write back to file
File.WriteAllLines(fullPath, txtLines, Encoding.UTF8);
}
}
To insert line by known string in file
InsertLineByKnownString(#"C:\MyFile.txt", "Some string in my lines", #"This is new line ");
public void InsertLineByKnownString(
string fullPath,
string lineToSearch,
string lineToAdd,
bool toBelow = false)
{
// Read entire file lines
var txtLines = File.ReadAllLines(fullPath).ToList();
// Specify insert location
int index = toBelow ? txtLines.IndexOf(lineToSearch) + 1 : txtLines.IndexOf(lineToSearch);
if (index > 0)
{
// Insert the line
txtLines.Insert(index, lineToAdd);
// Write back to file
File.WriteAllLines(fullPath, txtLines, Encoding.UTF8);
}
}
I'm trying to read a text file to two string arrays. Array1 is to be all the odd lines, array2 all the even lines. I then add all the items of array1 to a combobox and when that is selected, or as it gets typed, outputs array2 to a textbox.
So far, I have tried a few methods from here, but the big issue seems to be creating the arrays. I tried to get help here before, but the answers didn't actually answer my question. They must be arrays, not lists (which I tried and worked well). I am really confused by this whole thing and my attempted code is now rubbish:
private void ReadFile(string filePath, string customerPhone, string customerName)
{
string line = string.Empty;
var fileSR = new StreamReader(filePath);
bool number = true;
while((line = fileSR.ReadLine()) != null)
{
if (number)
{
customerPhone(line);
number = false;
}
else
{
customerName(line);
number = true;
}
}
fileSR.Close();
}
I'm losing confidence in this whole process, but I need to find a way to make it work, then I can learn why it does.
You are almost there, just use the List<string>.
private void ReadFile(string filePath, string customerPhone, string customerName)
{
string line = string.Empty;
using (var fileSR = new StreamReader(filePath))
{
bool number = true;
List<string> customerPhone = new List<string>();
List<string> customerName = new List<string>();
while((line = fileSR.ReadLine()) != null)
{
if (number)
{
customerPhone.Add(line);
number = false;
}
else
{
customerName.Add(line);
number = true;
}
}
fileSR.Close();
}
}
If you are interested only in Arrays, you could simply call customerName.ToArray() to convert it to an array.
Linq Solution
Alternatively you could use Linq and do this.
var bothArrays = File.ReadLines("filepath") // Read All lines
.Select((line,index) => new {line, index+1}) // index each line
.GroupBy(x=> x/2) // Convert into two groups
.SelectMany(x=> x.Select(s=>s.line).ToArray()) // Convert it to array
.ToArray();
You should use collections to return data, say IList<String>:
private static void ReadFile(String filePath,
IList<String> oddLines,
IList<String> evenLines) {
oddLines.Clear();
evenLines.Clear();
int index = 1; //TODO: start with 0 or with 1
foreach (String line in File.ReadLines(filePath)) {
if (index % 2 == 0)
evenLines.Add(line);
else
oddLines.Add(line);
index += 1;
}
}
using
List<String> names = new List<String>();
List<String> phones = new List<String>();
ReadFile(#"C:\MyDate.txt", names, phones);
// If you want array representation
String[] myNames = names.ToArray();
String[] myPhones = phones.ToArray();
// Let's print out names
Console.Write(String.Join(Envrironment.NewLine, names));
Please, notice, that using File.ReadLines usually more convenient than StreamReader which should be wrapped in using:
// foreach (String line in File.ReadLines(filePath)) equals to
using (var fileSR = new StreamReader(filePath)) {
while ((line = fileSR.ReadLine()) != null) {
...
}
}
This worked! I have these class level strings:
string cFileName = "customer.txt";
string[] cName = new string[0];
string[] cPhone = new string[0];
And then this in the Window Loaded event, but could be used in it's own method:
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
//read file on start
int counter = 0;
string line;
StreamReader custSR = new StreamReader(cFileName);
line = custSR.ReadLine();
while (custSR.Peek() != -1)
{
Array.Resize(ref cPhone, cPhone.Length + 1);
cPhone[cPhone.Length - 1] = line;
counter++;
line = custSR.ReadLine();
Array.Resize(ref cName, cName.Length + 1);
cName[cName.Length - 1] = line;
counter++;
line = custSR.ReadLine();
phoneComboBox.Items.Add(cPhone[cPhone.Length - 1]);
}
custSR.Close();
//focus when program starts
phoneComboBox.Focus();
}
I have a text file which contains user records.In the text file one user record is present in three lines of text file.Now as per my requirement i have to read first three lines for one User, Process it and insert into database and next three lines for second user and so on..
Here is the code that i have used for single line reading from text files..
if (System.IO.File.Exists(location) == true)
{
using (StreamReader reader = new StreamReader(location))
{
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
}
}
}
Please help me to read multi-lines , in this case 3 lines from text file ..
Thanks..
You could do something like:
if (System.IO.File.Exists(location) == true)
{
var lines=File.ReadAllLines(location);
int usersNumber = lines.Count() / 3;
for(int i=0; i < usersNumber; i++){
var firstField=lines[i*3];
var secondField=lines[i*3 +1];
var thirdField=lines[i*3 +2];
DoStuffs(firstField,secondField,thirdField);
}
if(lines.Count() > usersNumber *3) //In case there'd be spare lines left
DoSomethingElseFrom(lines, index=(usersNumber*3 +1));
}
You're reading all the lines of your file, counting how many users you have (group of 3), then for each group you're retrieving its associate info, and in the end you're processing the group of 3 fields related to the same user.
I have used a dummy dource file with this content:
line1_1 /*First line*/
line1_2
line1_3
line2_1 /*second line*/
line2_2
line2_3
line3_1 /*third line*/
line3_2
line3_3
line4_1 /*fourth line*/
line4_2
line4_3
string result = String.Empty;
string location = #"c:\users\asdsad\desktop\lines.txt";
if (System.IO.File.Exists(location) == true)
{
using (StreamReader reader = new StreamReader(location))
{
string line = String.Empty;
while ((line = reader.ReadLine()) != null) /*line has the first line in it*/
{
for(int i = 0; i<2; i++) /*only iterate to 2 because we need only the next 2 lines*/
line += reader.ReadLine(); /*use StringBuilder if you like*/
result += line;
}
}
result.Dump(); /*LinqPad Only*/
void Main()
{
var location = #"D:\text.txt";
if (System.IO.File.Exists(location) == true)
{
using (StreamReader reader = new StreamReader(location))
{
const int linesToRead = 3;
while(!reader.EndOfStream)
{
string[] currReadLines = new string[linesToRead];
for (var i = 0; i < linesToRead; i++)
{
var currLine = reader.ReadLine();
if (currLine == null)
break;
currReadLines[i] = currLine;
}
//Do your work with the three lines here
//Note; Partial records will be persisted
//var userName = currReadLines[0] ... etc...
}
}
}
}
I have a situation where I am given a text file with text formatted as follows:
C:\Users\Admin\Documents\report2011.docx: My Report 2011
C:\Users\Admin\Documents\newposter.docx: Dinner Party Poster 08
How would it be possible to trim the text file, so to trim the ":" and all characters after it.
E.g. so the output would be like:
C:\Users\Admin\Documents\report2011.docx
C:\Users\Admin\Documents\newposter.docx
Current Code:
private void button1_Click(object sender, EventArgs e)
{
using (StreamWriter sw = File.AppendText(#"c:\output.txt"))
{
StreamReader sr = new StreamReader(#"c:\filename.txt");
Regex reg = new Regex(#"\w\:(.(?!\:))+");
List<string> parsedStrings = new List<string>();
while (sr.EndOfStream)
{
sw.WriteLine(reg.Match(sr.ReadLine()).Value);
}
}
}
Not working :(
int index = myString.LastIndexOf(":");
if (index > 0)
myString= myString.Substring(0, index);
Edit - Added answer based on modified question. It can be condensed slightly, but left expanded for clarity of what's going on.
using (StreamWriter sw = File.AppendText(#"c:\output.txt"))
{
using(StreamReader sr = new StreamReader(#"input.txt"))
{
string myString = "";
while (!sr.EndOfStream)
{
myString = sr.ReadLine();
int index = myString.LastIndexOf(":");
if (index > 0)
myString = myString.Substring(0, index);
sw.WriteLine(myString);
}
}
}
Edited
StreamReader sr = new StreamReader("yourfile.txt");
Regex reg = new Regex(#"\w\:(.(?!\:))+");
List<string> parsedStrings = new List<string>();
while (!sr.EndOfStream)
{
parsedStrings.Add(reg.Match(sr.ReadLine()).Value);
}
sure. while reading each line, do a
Console.WriteLine(line.Substring(0,line.IndexOf(": "));
i'd use the answer given here Code to trim part of a text file in C# and find the 2nd occurrence and then use it in substring.
var s = #"C:\Users\Admin\Documents\report2011.docx: My Report 2011";
var i = GetNthIndex(s,':',2);
var result = s.Substring(i+1);
public int GetNthIndex(string s, char t, int n)
{
int count = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == t)
{
count++;
if (count == n)
{
return i;
}
}
}
return -1;
}
Assuming this is being done where the files are supposed to exist, you could handle this taking into account any colons in the (what I assume is) description by checking for the existence of the files after you get the index of the colon.
List<string> files = new List<string>();
files.Add(#"C:\Users\Admin\Documents\report2011.docx: My Report 2011");
files.Add(#"C:\Users\Admin\Documents\newposter.docx: Dinner Party Poster 08");
files.Add(#"C:\Users\Admin\Documents\newposter.docx: Dinner Party: 08");
int lastColon;
string filename;
foreach (string s in files)
{
bool isFilePath = false;
filename = s;
while (!isFilePath)
{
lastColon = filename.LastIndexOf(":");
if (lastColon > 0)
{
filename = filename.Substring(0, lastColon);
if (File.Exists(filename))
{
Console.WriteLine(filename);
isFilePath = true;
}
}
else
{
throw new FileNotFoundException("File not found", s);
}
}
}
Try this:
more faster:
string s = #"C:\Users\Admin\Documents\report2011.docx: My Report 2011";
string path = Path.GetDirectoryName(s) + s.Split(new char[] { ':' }) [1];
Console.WriteLine(path); //C:\Users\Admin\Documents\report2011.docx
you need import System.IO
you could use split:
string[] splitted= myString.Split(':');
Then you get an array where you take the first one.
var mySplittedString = splitted[0]
Have a look here if you need more information on this.
EDIT: In your case you get an array with the size of at least 3 so you need to get splitted[0] and splitted[ 1]