reading separate lines of data in a grid using c# - c#

Given a data text file which looks like
21,7,11
20,10,12
17,7,18
These represent height, temperature and carbon percentage.
I have read in the file as a .txt file using system.io. Is this correct? from here how would I calculate the maximum temperature?
{
string s;
System.IO.StreamReader inputFile = new System.IO.StreamReader(DataFile);
s = inputFile.ReadLine();
int noDataLines = int.Parse(s);
}

You need to read all the lines and compare each value to find out max temperature.
Something like below (untested code!) should be done. There are lot of assumptions in this code and you may have to change it to suit your case.
{
string s;
int maxValue=-1, temp=-1;
using(System.IO.StreamReader in = new System.IO.StreamReader(DataFile))
{
while (in.Peek() >= 0)
{
s = in.ReadLine();
if(int.tryParse(s.split(",")[1], out temp)
{
if(temp>maxValue)
maxValue = temp;
}
}
}
}

You will most likely want to create a two-dimensional list or array, and in this example I am using a list.
{
List<List<int>> intList = new List<int>(); // This creates a two dimensional list.
System.IO.StreamReader inputFile = new System.IO.StreamReader(DataFile);
string line = inputFile:ReadLine();
while (line != null) // Iterate over the lines in the document.
{
intList.Add( // Adding a new row to the list.
line.Split(',').Select(int.Parse).ToList()
// This separates the line by commas, and turns it into a list of integers.
);
line = inputFile:ReadLine(); // Move to the next row.
}
}
I will admit that this is certainly not a very concise method of doing it, but it is relatively straightforward.
To access it, do this:
int element = intList[1, 2]; // Accessing 2nd row, 3rd column.

Related

Trying to read the previous line when reading a certain line from a text file in C#

I'm reading a text file that contains continents , countries , capitals and the population of those countries. Here is the text file image of file with info. I then input a value , let's say I input "Birmanie" the StreamReader instance then takes the info from the NEXT line which would be "Bolivie". "Pays" is the input. My goal is to read the line of the country that the user inputs and then later on extract the info from that line.
Here's my code.
while (!srRecherche.EndOfStream)
{
lireLigneRechercher = srRecherche.ReadLine();
if (lireLigneRechercher.IndexOf(Pays,StringComparison.CurrentCultureIgnoreCase) >= 0)
{
for (int i = 1; i <= 35; i++)
{
lireCharacteres += (char)srRecherche.Read();
}
for (int i = 1; i <= 74; i++)
{
srRecherche.Read();
}
}
}
The for loops are there so that I can skip through the rest of the information and only read the country's name.
Here is an example that might help. The numbers (index positions on the lines) are completely made up, but hopefully you'll see where I'm going. Instead of trying to read with a reader, I would read all the lines and put them into a collection of some sort. I used a struct and a HashSet below, but you could use a class and a List, or a SortedSet, or a Collection, or many other options. By transforming each line into a struct/class, you gain the liberty of doing any sort of analysis or manipulation you want without having to back-track. Since your data seems relatively fixed, you can also gain some advantage by storing the entire list in memory and then finding (in your cached list) what the user asks for with a Where() or FirstOrDefault() instead of reading the file with each new input.
class Program
{
static void Main(string[] args)
{
string userInput = "Birmanie";
var lines = File.ReadAllLines("c:\\myfile.txt");
HashSet<FileLine> fileLines = new();
foreach (var line in lines)
{
var fileLine = new FileLine()
{
Country = line.Substring(0, 25).Trim(),
City = line.Substring(35, 20).Trim(),
Population = Convert.ToInt32(line.Substring(55, 20).Trim()),
Continent = line.Substring(75).Trim()
};
fileLines.Add(fileLine);
}
int pop = fileLines.FirstOrDefault(l => l.City == userInput).Population;
}
}
struct FileLine
{
public string Country;
public string City;
public int Population;
public string Continent;
}

How can I read a text file and write its values to an array

I have a text file with values and I need to read them. The first line is the size of my array and the second line has values that I need to put into to an array.
My main looks like:
public static void Main()
{
int n,i=0,k=1;
var plik_wejsciowy = new StreamReader("In0201.txt");
StreamWriter plik_wyjsciowy = new StreamWriter("Out0201.txt");
string[] wejscie = plik_wejsciowy.ReadLine().Split(' ');
n = int.Parse(wejscie[0]);
int[] tab = new int[n];
for (i=0;i<n;i++)
{
tab[i] = int.Parse(wejscie[k]);
k++;
}
plik_wyjsciowy.Close();
}
I don't really know what to do and where I'm making a mistake.
We can make life easier; you don't really need to use the first line to track how many lines are in the file; you can just read the lines into an array (skip the first if it's only a line counter) then parse the rest and turn them into an array:
var x = File.ReadAllLines(path).Skip(1).Select(int.Parse).ToArray();
If you switch the first line being a counter of lines, remove the Skip(1)

Updating line of a file if array element matches text box

I have a method which currently reads all lines of a directory file (3 fields per line) and updates a directory array with a record of text box entries if the extension code entered matches an extension code field in the file.
I had the updated directory array displaying to a list view, as soon as I attempted to update the directory file with the updated array, it all went downhill! Edit to clarify: with the latest version of the code below, the array no longer displays to the list view, and the file is not updated. No errors are thrown.
public void updateName()
{
int count = 0;
string[] lines = File.ReadAllLines(directoryFile);
// Set size of directory array equal to number of lines in file
int lineCount = lineCounter();
directory = new record[lineCount];
record currentRecord = new record();
// Iterate through each line in file
foreach (string line in lines)
{
// Split current line into three fields
string[] fields = line.Split(',');
// Save current line as new record with surname, forename and extCode fields
currentRecord.surname = fields[0];
currentRecord.forename = fields[1];
currentRecord.extCode = Convert.ToInt32(fields[2]);
// If extension code in current record matches text box entry
if (Convert.ToInt32(fields[2]) == Convert.ToInt32(txtExtCode.Text))
{
// Change surname and forname fields to match text box entries
currentRecord.surname = txtForename.Text;
currentRecord.forename = txtSurname.Text;
using (StreamWriter writer = new StreamWriter(directoryFile))
{
for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
{
if (currentLine == count)
writer.WriteLine(currentRecord);
else
writer.WriteLine(lines[currentLine - 1]);
}
}
}
// Save currentRecord as next element in directory array, then increment
directory[count] = currentRecord;
count++;
}
}
You don't need a linecounter(). The number of lines is lines.Length.
But why do you need this directory array? You are filling it, but you are not using it anywhere.
Another major problem is that you are creating a StreamWriter inside the foreach loop. You should open the file before the loop and close it after the loop to make it work.
Also, you are mixing writing currentRecord which is of type record and writing lines of type string to the output file. This cannot work.
You are also putting txtForename.Text into currentRecord.surname instead of currentRecord.forename and vice versa.
I suggest to first apply the change in the lines array and then to write this lines array back to to file with File.WriteAllLines which is the symmetric operation to File.ReadAllLines.
I'm applying the change directly to fields array, so that I can convert it back to a string with String.Join (it is the symmetric operation to String.Split).
public void updateName()
{
// Do this conversion before the loop. We need to do it only once.
int selectedCode = Convert.ToInt32(txtExtCode.Text);
string[] lines = File.ReadAllLines(directoryFile);
for (int i = 0; i < lines.Length; i++)
{
// Split current line into three fields
string[] fields = lines[i].Split(',');
int extCode = Convert.ToInt32(fields[2]);
if (extCode == selectedCode)
{
fields[0] = txtSurname.Text;
fields[1] = txtForename.Text;
lines[i] = String.Join(",", fields);
// If the extension code is unique, leave the for-loop
break;
}
}
File.WriteAllLines(directoryFile, lines);
}
I also use for instead of foreach in order to have an index i, so that I can replace a single line in the lines array at a specific index.
I don't know if the extension code in the directory file is unique. If it is, you can exit the for loop prematurely with break.

c# Read lines from a file and replace with text from DataGridView Data

I am relatively new to c#, I am creating an windows application which would read all the lines from a text file. The user will input the string which needs to be replaced in Column[0] and the text with which it needs to be replaced in Column1 of the DataGridView control.
I have created two string arrays column0 and column1.
However, I am getting an error while replacing the string in line (column0, column1)
The following is my code:
string[] column0 = new string[dgvMapping.Rows.Count];
string[] column1 = new string[dgvMapping.Rows.Count];
int j = 0;
foreach(DataGridViewRow row in dgvMapping.Rows)
{
if (!string.IsNullOrEmpty(Convert.ToString(row.Cells[0].Value)))
{
column0[j] = Convert.ToString(row.Cells[0].Value);
column1[j] = Convert.ToString(row.Cells[1].Value);
j++;
}
}
var _data = string.Empty;
String[] arrayofLine = File.ReadAllLines(ofd.FileName);
using (StreamWriter sw = new StreamWriter(ofd.FileName + ".output"))
{
for (int i = 0; i < arrayofLine.Length; i++)
{
string line = arrayofLine[i];
line = line.Replace(column0[i], column1[i]);
sw.WriteLine(line);
}
}
I am using OpenFileDialog to select the file.
The Error While Executing:
You are looping around a file of unknown number of lines, and assuming that the count of lines in the grid is exactly the same as that of the file. Your code will only work if both the file and the gridView have the same number of lines.
One of the solutions, is to loop over the array of lines (as you have already did), and search for the GridViewRow in which the current line contains a key in your DGV. If this is the case, then replace all the occurences of the key by the value (obtained from the gridView) in that line, otherwise do nothing.
Check out the code below :
// Convert the row collection to a list, so that we could query it easily with Linq
List<DataGridViewRow> mySearchList = dataGridView1.Rows.Cast<DataGridViewRow>().ToList();
const int KEY_INDEX = 0; // Search index in the grid
const int VALUE_INDEX = 1; // Value (replace) index in the grid
for (int i = 0; i < arrayofLines.Length; i++)
{
string line = arrayofLines[i];
// Get data grid view Row where this line contains the key string
DataGridViewRow matchedRow = mySearchList.FirstOrDefault(obj => line.Contains(obj.Cells[KEY_INDEX].Value.ToString()));
// If this row exists, replace the key with the value (obtained from the grid)
if (matchedRow != null)
{
string key = matchedRow.Cells[KEY_INDEX].Value.ToString();
string value = matchedRow.Cells[VALUE_INDEX].Value.ToString();
line = line.Replace(key, value);
sw.WriteLine(line);
}
else
{
// Otherwise, do nothing
}
}
Stuartd is correct… there are more lines in the file than there are elements to search. I am not sure what the search is doing in a sense that it seems somewhat limited. The code appears to search for each item depending on what line it is. The searched value in column 0 and the replace value in column 1 of row 0… will only replace those values for the FIRST line in the file. The DataGridViews second row values will search/replace only the SECOND line and so on. This seems odd.
Example the two string arrays (column0 and column1) have sizes set to the number of rows in dgvMapping. Let’s say there are 5 rows in the grid, then the array sizes will be 5 strings. When you start the loop to write the strings, the loop starts at 0 and stops at the number of lines in the file. The code uses this i variable as an index into the two arrays. If there are more lines in the file, than there are rows in the grid… then you will get the error.
Again, this seems odd to do the search and replace this way. Assuming you want to search for EACH term in all the rows in column 0 and replace the found searched string with the replace string in column 1, then you will need to loop through EACH row of the grid for EACH line in the file. This will replace ALL the search/replace terms in the grid with ALL the lines in the file. If this is what you what to accomplish below is one way to achieve this, however…there are possibly better ways to accomplish this.
The code below reads the file into one big string. Then the code loops through ALL the grid rows to search/replace the strings in the big string. Hope this helps.
string bigString = File.ReadAllText(ofd.FileName);
try {
using (StreamWriter sw = new StreamWriter(ofd.FileName + ".output")) {
for (int k = 0; k < dgvMapping.Rows.Count; k++) {
if (dgvMapping.Rows[k].Cells[0].Value != null && dgvMapping.Rows[k].Cells[1].Value != null) {
string searchTerm = dgvMapping.Rows[k].Cells[0].Value.ToString();
string replaceTerm = dgvMapping.Rows[k].Cells[1].Value.ToString();
if (searchTerm != "") {
bigString = bigString.Replace(searchTerm, replaceTerm);
} else {
// one of the terms is empty
}
} else {
// one of the terms is null}
}
}
sw.WriteLine(bigString);
}
}
catch (Exception ex) {
MessageBox.Show("Write Erro: " + ex.Message);
}

How can I copy an Array to another minus user specified Elements AND write and replace the new list the a .txt file

Here is what I have so far, obviously you can subtract arrays the way i did. And I also need to know how to write the new list to a .txt file that i already have ("records.txt")
public static int deleteRecord(string num)
{
int amount;
int.TryParse(num, out amount);
string[] arrayRecords = File.ReadAllLines("Records.txt").ToArray();
string[] newArrayRecords = arrayRecords - arrayRecords[amount];
for (int i = 0; i < amount; i++)
{
Console.WriteLine(newArrayRecords[amount]);
}
Console.WriteLine(amount);
return amount;
}
I assume that you want to delete a particular value from a file and that is why you have chosen the "num" parameter to be a string.
If so then this will work:
public static void deleteRecord(string num)
{
var lines = File.ReadAllLines("Records.txt").ToList();
if (lines.Remove(num) == true)
{
File.WriteAllLines("Records.txt", lines.ToArray<string>());
}
}
There are a couple of things to point out in your code. Firstly in your example, if you couldn't convert num to an int then you would be trying to remove the value of 0 from your file - which you may not want.
Secondly File.ReadAllLines already returns an Array of strings, so you don't need the .ToArray() at the end. In fact that converts the string[] array to an object[] array - which is not what you want.
I've converted it to a List as they are easier to work with. I only save the file if the item has been removed.
Hope that helps...
I presume that you want to remove the line that contains specified amount, if so you can try this:
var lines = File.ReadLines("Records.txt")
.Where(x => !x.Contains(amount.ToString());
// this will replace all prev. lines with the new ones
File.WriteAllLines("Records.txt", lines);
If you want to remove all lines that comes before this line then you can try:
var allLines = File.ReadLines("Records.txt");
var line = allLines.Where(x => x.Contains(amount.ToString()).First();
var lineIndex = allLines.IndexOf(line);
File.WriteAllLines("Records.txt",lines.GetRange(lineIndex, allLines.Count - lineIndex));
Ofcourse that answer assumes that there is line that contains amount.If there isn't then second code snippet could possibly throw exception.

Categories