How do I read a file for a specific line - c#

I'm making a console application and I need to be able to write, search and delete entries from within text files, I can write files into a notepad file but that's basically it, this is what I have to read the file:
public static void SearchDetails()
{
Console.WriteLine("Enter ID Number");
string myfile = System.IO.File.ReadAllText(#"C:\\file.txt");
System.Console.WriteLine(myfile);
}
This brings up all the text in the file but I need to be able to search for a specific number within the file and then brings up the next three lines below it. How to I get it to read the input so that it matches with a number in the text file and then bring up the next 3 lines?

So you can do whatever you want with the results but something like this is what you want
// Read the file and display next three lines
System.IO.StreamReader file = new System.IO.StreamReader("c:\\file.txt");
string line;
int lineCnt = 3;
while((line = file.ReadLine()) != null)
{
if (line.Contains(myID) & !bGet)
{
bool bGet = true;
}
if (bGet && lineCnt > 0)
{
bool bGet = true;
Console.WriteLine (line);
lineCnt--;
}
if(lineCnt == 0) {break;}
}
file.Close();
// Suspend the screen.
Console.ReadLine();

Considering you question and comments to answer, the final answer would be:
public static void SearchDetails()
{
Console.WriteLine("Enter ID Number");
int Id = 0;
int.TryParse(Console.ReadLine(), out Id);
string[] lines = System.IO.File.ReadAllLines(#"C:\\file.txt");
List<string> IdLines = lines.Where((x, i) => i % 4 == 0).ToList();
int IdLine = IdLines.IndexOf(Id);
if (IdLine != -1)
{ //then result found
//Id is what user searched for or
// string Id = lines[IdLine*4];
//string[] results = lines.Where((x, i) => i > IdLine * 4 && i < IdLine * 4 + 4).ToArray();
for(int i=IdLine*4;i<IdLine*4+4;i++)
System.Console.WriteLine(lines[i]);
}
else
{
Console.WriteLine("no results!");
}
}

Related

Writing a program in C# where depending on the Id (txtBxNumber) it will either update or create a new record in a text file and a Rich Text Box

fileName = txtBxFileNamePath.Text;
if (File.Exists(fileName))
{
if (txtBxDate.Text != null && txtBxNumber.Text != null && txtBxUnit.Text != null && txtBxUnitPrice.Text != null && txtBxShipTo.Text != null
&& txtBxOrdered.Text != null && richTxBxDesc.Text != null)
{
try
{
int higherThanZero = Int32.Parse(txtBxNumber.Text);
if (higherThanZero > 0)
{
using (StreamReader reader = File.OpenText(fileName))
{
string[] lines = File.ReadAllLines(fileName);
for (int i = 0; i < lines.Length - 1; i++)
{
string firstNum = lines[i].Substring(0, 2);
if (firstNum == txtBxNumber.Text)
{
string record = "hello ";
lines[i].Replace(lines[i], record);
}
else
{
int orderNum = Int32.Parse(txtBxOrdered.Text);
int unitPriceNum = Int32.Parse(txtBxUnitPrice.Text);
double tax = .13;
int taxInt = (int)tax;
int amount = orderNum * unitPriceNum;
string amountStr = amount.ToString();
int amountTotal = amount * taxInt;
string amountTotalStr = amountTotal.ToString();
amountList.Add(amountStr);
amountTotalList.Add(amountTotalStr);
string record = amountTotalStr.PadRight(30) + amountStr.PadRight(30);
richTxtBxRecord.Text += record + "\n";
using (StreamWriter write = new StreamWriter(fileName, true))
{
write.WriteLine(record + "\n");
write.Close();
}
}
}
}
}
else
{
richTxtBxError.Text += "Textbox Number must contain a digit higher than 0 ";
}
}
catch
{
richTxtBxError.Text += "Please make sure number text box is a digit";
}
}
else
{
richTxtBxError.Text += "please make sure that no text boxes are empty";
}
}
else
{
richTxtBxError.Text += "Please select a file that already exists";
}
I am having an issue where once i get past the try-catch statement "please make sure number is a digit, no code executes. I am trying to obtain the first few characters in a text file and match it with the users input. If the input is the same as what is already inserted in the text file, i update the whole record. If there is no match (non existent number) i write in a brand new record.
I can't quite follow your logic, but I tried. You should be able to take this code and do what you want (whatever it is).
I started by declaring some class level variables.
private DateTime _dateValue;
private int _numberValue;
private decimal _unitPrice;
private int _numberOrdered;
Then, since you have so many preconditions and so many text boxes, I factored out the validation and setting of these variables. It makes the logic (whatever it supposed to be) much easier to follow:
private bool ValidateUserEntry()
{
bool isError = false;
if (!File.Exists(txtBxFileNamePath.Text))
{
AddError("File Name must exist");
isError = true;
}
if (txtBxDate.Text == string.Empty || !DateTime.TryParse(txtBxDate.Text, out var _dateValue))
{
AddError("The date must be a valid date");
isError = true;
}
if (txtBxNumber.Text == string.Empty || !int.TryParse(txtBxNumber.Text, out _numberValue) ||
_numberValue <= 0)
{
AddError("You must enter a number greater than 0 for [Number]");
isError = true;
}
if (txtBxUnitPrice.Text == string.Empty || !decimal.TryParse(txtBxUnitPrice.Text, out _unitPrice) ||
_unitPrice <= 0.0m)
{
AddError("The unit price must be a positive decimal number");
isError = true;
}
if (txtBxShipTo.Text == string.Empty)
{
AddError("A ship to address is required");
isError = true;
}
if (txtBxOrdered.Text == string.Empty || !int.TryParse(txtBxOrdered.Text, out _numberOrdered) ||
_numberOrdered <= 0)
{
AddError("The Number ordered must be a number greater than 0");
isError = true;
}
if (richTxBxDesc.Text == string.Empty)
{
AddError("A description is required");
isError = true;
}
return !isError;
}
I also added two utility functions for managing the error list:
private void ClearError()
{
richTxtBxError.Text = string.Empty;
}
private void AddError(string errorMessage)
{
richTxtBxError.Text += (errorMessage + Environment.NewLine);
richTxtBxError.SelectionStart = richTxtBxError.Text.Length;
richTxtBxError.SelectionLength = 0;
}
Now comes the real code. Near as I can tell, you want to scan a text file. If the number in the first few character positions matches a number in your input, then you change the line to some constant text. Otherwise, you want to do a calculation and put the results of the calculation on the line of text.
My input file looks like this:
1 First
2 Second
3 Third
12 Twelth
13 Thirteenth
34 Thirty-fourth
and the code that I run looks like what's below. The logic makes no sense, but it was what I could discern from your code. Instead of trying to do things on the fly to a file (which never really turns out well unless you are really careful), I gather the output into a List<string>. Once I have all the output, I put it in a text box control and overwrite the file.
ClearError();
//check pre-conditions
if (!ValidateUserEntry())
{
return;
}
string[] lines;
using (StreamReader reader = File.OpenText(txtBxFileNamePath.Text))
{
lines = File.ReadAllLines(txtBxFileNamePath.Text);
}
List<string> newLines = new List<string>();
for (var lineIndex = 0; lineIndex < lines.Length; ++lineIndex)
{
var line = lines[lineIndex];
if (line.Length > 2 && int.TryParse(line.Substring(0, 2), out var linePrefixNumber) &&
linePrefixNumber == _numberValue)
{
newLines.Add("Bingo, hit the right record");
}
else
{
decimal tax = .13m;
var amount = _numberOrdered * _unitPrice;
var amountTotal = amount * (1m + tax);
//amountList.Add(amount.TosString());
//amountTotalList.Add(amountTotal.ToString());
var newRecord = $"{amountTotal,30:C}{amount,30:C}";
newLines.Add(newRecord); //every record but one will be the same, but, such is life
}
}
//at this point, the newLines list has what I want
//put it in the text box
richTxtBxRecord.Text = string.Join(Environment.NewLine, newLines);
//and write it out
using (StreamWriter write = new StreamWriter(txtBxFileNamePath.Text, append:false))
{
write.Write(richTxtBxRecord.Text);
write.Flush();
}
With inputs that look like:
Number: 12
Number Ordered: 3
Unit Price: 1.23
The output (oddly enough - but it's what I could figure from your code) looks like:
$4.17 $3.69
$4.17 $3.69
$4.17 $3.69
Bingo, hit the right record
$4.17 $3.69
$4.17 $3.69
You can see that the input line that had the 12 at the start gets switched for bingo. The rest get the same information. I'm sure that's not what you want. But, with this code, you should be able to get something that you'd like.
Also note that I treat all the currency values as decimal (not int or double). For the life of me, I have no idea what you were trying to do with the taxInt variable (it will always be zero the way you have coded it). Instead, I did a rational tax calculation.
All of the code below the catch block is inside an else block, so I wouldn't expect it to execute. If you want something to execute after the catch, remove it from the else block.

How can I make 1 button click fill out 2 different text boxes

I need help making this program fill out 2 different text boxes. It works if I only use it to fill out 1 text box using a First name. But when I try and add another text box to generate a random Last name it just seems to do fail.
private void button1_Click(object sender, EventArgs e)
{
Random r = new Random();
int currentLine = 1;
string pick = null;
foreach (string line in File.ReadLines("C:\\First Names.txt"))
{
if (r.Next(currentLine) == 0)
{
pick = line;
}
++currentLine;
textBox1.Text = pick;
}
Random n = new Random();
int currentLine1 = 1;
string pick1 = null;
foreach (string line1 in File.ReadLines("C:\\Last Names.txt"))
{
if (n.Next(currentLine1) == 0)
{
pick1 = line1;
}
++currentLine1;
textBox2.Text = pick1;
}
}
}
}
Check whether the path for the file is appropriate.
You need not create two objects for the same class and access them differently.One object is enough.
3.Check whether data is there in the file or not.`Random r = new Random();
int currentLine = 1;
string pick = null;
foreach (string line in File.ReadLines("C:\\First Names.txt"))
{
if (r.Next(currentLine) == 0)
{
pick = line;
}
++currentLine;
textBox1.Text = pick;
}
currentLine=0;pick=0;
foreach (string line in File.ReadLines("C:\\Last Names.txt"))
{
if (r.Next(currentLine) == 0)
{
pick = line;
}
++currentLine;
textBox2.Text = pick;
}
}`
If the first iteration gets the value, then the second must also get. Else there is some problem with Text file or the 'textBox2' is not the correct ID you are looking for.

I want to read text files from a folder?

In the code Below:
I read from just one text file, but i want to read from multiple files in a folder and then assign the variables and create a new instance of appointment for each file??
public bool Load()
{
DateTime start = new DateTime(2000,01,01);
int length = 0;
string screenDiscription = "";
string line;
int i = 1;
StreamReader sr = new StreamReader("Appointments.txt");
if (!File.Exists("Appointments.txt"))
{
return true;
}
while ((line = sr.ReadLine()) != null)
{
if (i % 4 == 1)
{
start = DateTime.ParseExact(line, "dd/MM/yyyy HHmm", CultureInfo.CreateSpecificCulture("en-GB"));
}
if (i % 4 == 2)
{
length = int.Parse(line);
}
if (i % 4 == 3)
{
screenDiscription = line;
apps.Add(new Appointment(start, length, screenDiscription));
}
i++;
}
sr.Close();
return true;
}
To get the all the files in a directory use the function System.IO.Directory.GetFiles("directoryPath");
Read this page for the documentation
https://msdn.microsoft.com/en-us/library/system.io.directory(v=vs.110).aspx

Name, Identity Number And School Number Control Void

I'm using C# and I have a function for check this values. ( Name, Identity Number And School Number )
My records on text file.
If two or more same name and surname (different identity number and school number) in text file, I need to show all of them.
How Can I do it with loop ?
Note = identityBox is my TextBox name and identity number in there. This code just run for one record. This is identityFounder Code. Name and Surname founder Code is same with this. I will use next and previous buttons for see all records. Here is the C# Codes. Help me please. Thank you.
void identityFounder()
{
int inout = 0;
double identityNo = Convert.ToDouble(founderBox.Text);
String[] line = File.ReadAllLines("C:\\OgrenciBilgisi_v2.txt");
for (int i = 0; i < line.Length; i++)
{
if (line[i].Contains(identityNo.ToString()))
{
temp = i;
inout = 1;
break;
}
else
{
inout = 0;
continue;
}
}
if (inout == 1)
{
name.Text = line[temp - 3];
surname.Text = line[temp - 2];
address.Text = line[temp - 1];
identity.Text = line[temp];
school.Text = line[temp + 1];
number.Text = line[temp + 2];
faculty.Text = line[temp + 3];
deparrtment.Text = line[temp + 4];
class.Text = line[temp + 5];
}
else
{
MessageBox.Show("Record cannot found file.","Warning",MessageBoxButtons.OK
,MessageBoxIcon.Information);
}
}
First, a couple of quick asides:
inout should be a bool, not an int.
You can drop the else block; it isn't doing anything.
Now, more broadly, what you want to do is keep track of which names you've already seen as you parse the records. This is actually going to be faster and easier if you parse all of the identities at once. Since your lines are not structured except by order, the only way to do this is with a state machine.
I would just make a small console app that parses the text file, looking for duplicate names, and if it finds any then report the file name (or print the entire file to the screen or whatever; I'm not clear on what you mean by "show all of them"). Maybe something like:
struct Record
{
public string Name, Surname;
public int Identity, School;
}
class Program
{
static void Main(string[] args)
{
const string path = #"C:\OgrenciBilgisi_v2.txt";
var position = 0;
var record = new Record();
var records = new Dictionary<string, Record>(); // key is the concatenation of name and surname
using (var reader = new StreamReader(path))
{
var line = reader.ReadLine();
if (line == "---") // TODO use your record delimiter here
{
// start of new record. compare the existing one and commit it if all fields have been written to
if (position == 9)
{
// compare records
var key = record.Name + record.Surname;
if (records.ContainsKey(key))
{
// this is a duplicate student name. confirm that the id and school # are different
if (records[key].Identity == record.Identity &&
records[key].School == record.School)
{
// id and school are the same, so this is an entirely duplicate record
}
else
{
// id and school are different, but name and surname are the same
// TODO: show all records
return;
}
}
else
{
records.Add(key, record);
}
}
else
{
Console.Error.WriteLine("Not all fields in record. Malformed data.");
}
position = 0;
record = new Record();
}
else
{
switch (position)
{
case 0:
record.Name = line;
break;
case 1:
record.Surname = line;
break;
case 3:
int id;
if (int.TryParse(line, out id))
{
record.Identity = id;
} // else there's an error
break;
case 4:
int school;
if (int.TryParse(line, out school))
{
record.School = school;
} // else there's an error
break;
}
position++;
}
}
}
}
This assumes that your data is pretty well formatted; adding error checking is left as an exercise for the reader :)

c# search string in txt file

I want to find a string in a txt file if string compares, it should go on reading lines till another string which I'm using as parameter.
Example:
CustomerEN //search for this string
...
some text which has details about the customer
id "123456"
username "rootuser"
...
CustomerCh //get text till this string
I need the details to work with them otherwise.
I'm using linq to search for "CustomerEN" like this:
File.ReadLines(pathToTextFile).Any(line => line.Contains("CustomerEN"))
But now I'm stuck with reading lines (data) till "CustomerCh" to extract details.
If your pair of lines will only appear once in your file, you could use
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.Skip(1) // optional
.TakeWhile(line => !line.Contains("CustomerCh"));
If you could have multiple occurrences in one file, you're probably better off using a regular foreach loop - reading lines, keeping track of whether you're currently inside or outside a customer etc:
List<List<string>> groups = new List<List<string>>();
List<string> current = null;
foreach (var line in File.ReadAllLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
current = new List<string>();
else if (line.Contains("CustomerCh") && current != null)
{
groups.Add(current);
current = null;
}
if (current != null)
current.Add(line);
}
You have to use while since foreach does not know about index. Below is an example code.
int counter = 0;
string line;
Console.Write("Input your search text: ");
var text = Console.ReadLine();
System.IO.StreamReader file =
new System.IO.StreamReader("SampleInput1.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains(text))
{
break;
}
counter++;
}
Console.WriteLine("Line number: {0}", counter);
file.Close();
Console.ReadLine();
With LINQ, you could use the SkipWhile / TakeWhile methods, like this:
var importantLines =
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.TakeWhile(line => !line.Contains("CustomerCh"));
If you whant only one first string, you can use simple for-loop.
var lines = File.ReadAllLines(pathToTextFile);
var firstFound = false;
for(int index = 0; index < lines.Count; index++)
{
if(!firstFound && lines[index].Contains("CustomerEN"))
{
firstFound = true;
}
if(firstFound && lines[index].Contains("CustomerCh"))
{
//do, what you want, and exit the loop
// return lines[index];
}
}
I worked a little bit the method that Rawling posted here to find more than one line in the same file until the end. This is what worked for me:
foreach (var line in File.ReadLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
{
current = new List<string>();
current.Add(line);
}
else if (line.Contains("CustomerEN") && current != null)
{
current.Add(line);
}
}
string s = String.Join(",", current);
MessageBox.Show(s);

Categories

Resources